デフォルトでtabindex=1に背景色がかかるようにし、他の要素をクリックした時に背景色が変わる
:focus-within
擬似クラスにより .hoge
がフォーカスを持つかどうかを調べ、持っていない場合最初の .hoge
へスタイルを適用する、というように質問者さんの実現したい装飾は可能です (動作確認用リンク)。
HTML
1<div class="tab">
2 <div class="hoge" tabindex="1">
3 <p class="item-name">Section 1</p>
4 <p class="description">description 1</p>
5 </div>
6
7 <div class="hoge" tabindex="2">
8 <p class="item-name">Section 2</p>
9 <p class="description">description 2</p>
10 </div>
11
12 <div class="hoge" tabindex="3">
13 <p class="item-name">Section 3</p>
14 <p class="description">description 3</p>
15 </div>
16</div>
17
18<input type="text" value="Section 1" id="input-item">
19<input type="text" value="description 1" id="input-description">
CSS
1.tab:not(:focus-within) > .hoge:first-child,
2.hoge:focus {
3 background: red;
4}
その中のPタグの要素を抜き出す方法を知りたい
これは JavaScript で行います。フォーカスに変化があったとき、各タブのいずれかがフォーカスを持つ場合はそのタブのテキストを、いずれの要素もフォーカスを持たない場合は最初のタブのテキストを input
タグへ設定すれば良いことになります。そのため、 focusin
, focusout
イベントを用いて以下のように書くことが出来ます (動作確認用リンク)。
JavaScript
1const tab = document.querySelector(".tab");
2const item = document.getElementById("input-item");
3const description = document.getElementById("input-description");
4
5const text = (selector, target = tab.firstElementChild) =>
6 target.querySelector(selector).textContent.trim();
7
8tab.addEventListener("focusin", event => {
9 const target = event.target;
10 [item.value, description.value] = [
11 text(".item-name", target),
12 text(".description", target)
13 ];
14});
15
16tab.addEventListener("focusout", event => {
17 if (!tab.contains(event.relatedTarget))
18 [item.value, description.value] = [
19 text(".item-name"),
20 text(".description")
21 ];
22});
上記の 2 つを合わせると、以下のようになり、これはタブが 3 つ以上に増えたとしても対応出来ていることがわかります (動作確認用リンク)。
HTML
1<div class="tab">
2 <div class="hoge" tabindex="1">
3 <p class="item-name">Section 1</p>
4 <p class="description">description 1</p>
5 </div>
6
7 <div class="hoge" tabindex="2">
8 <p class="item-name">Section 2</p>
9 <p class="description">description 2</p>
10 </div>
11
12 <div class="hoge" tabindex="3">
13 <p class="item-name">Section 3</p>
14 <p class="description">description 3</p>
15 </div>
16
17 <div class="hoge" tabindex="4">
18 <p class="item-name">Section 4</p>
19 <p class="description">description 4</p>
20 </div>
21
22 <div class="hoge" tabindex="5">
23 <p class="item-name">Section 5</p>
24 <p class="description">description 5</p>
25 </div>
26</div>
27
28<input type="text" value="Section 1" id="input-item">
29<input type="text" value="description 1" id="input-description">
CSS
1.tab:not(:focus-within)>.hoge:first-child,
2.hoge:focus {
3 background: red;
4}
JavaScript
1const tab = document.querySelector(".tab");
2const item = document.getElementById("input-item");
3const description = document.getElementById("input-description");
4
5const text = (selector, target = tab.firstElementChild) =>
6 target.querySelector(selector).textContent.trim();
7
8tab.addEventListener("focusin", event => {
9 const target = event.target;
10 [item.value, description.value] = [
11 text(".item-name", target),
12 text(".description", target)
13 ];
14});
15
16tab.addEventListener("focusout", event => {
17 if (!tab.contains(event.relatedTarget))
18 [item.value, description.value] = [
19 text(".item-name"),
20 text(".description")
21 ];
22});