特定要素内にaタグやbuttonタグなど、フォーカス可能な要素があるかどうを判定したいということがあったので、その際に調べた内容をメモ。
サンプルコード
実装方法としては、フォーカス可能な要素の一覧を作成して、それらの要素が特定要素内に存在するかどうかで調べます。
// フォーカス可能な要素一覧
const focusableSelector = `
a[href],
button:not([disabled]),
input:not([disabled]):not([type="hidden"]),
textarea:not([disabled]),
select:not([disabled]),
summary,
area[href],
[tabindex]:not([tabindex="-1"])
`;
const sample = document.querySelectorAll('.sample');
sample.forEach(function(element, index) {
// 対象要素内にあるフォーカス可能な要素を取得して、1件以上あればtrue
const focusableElements = element.querySelectorAll(focusableSelector);
console.log(index, focusableElements.length > 0);
});
実際に動作を試してみます。
<div class="sample">
<p>0.なし</p>
</div>
<div class="sample">
<a href="#">1.href付きリンク</a>
</div>
<div class="sample">
<a>2.href無しリンク</a>
</div>
<div class="sample">
<button>3.ボタン</button>
</div>
<div class="sample">
<button disabled>4.ボタン(disabled)</button>
</div>
<div class="sample">
<p>5.input</p>
<input type="text">
</div>
<div class="sample">
<p>6.input disabled</p>
<input type="text" disabled>
</div>
<div class="sample">
<p>7.input readonly</p>
<input type="text" readonly>
</div>
<div class="sample">
<p>8.input type=hidden</p>
<input type="hidden">
</div>
<div class="sample">
<p>9.textarea</p>
<textarea></textarea>
</div>
<div class="sample">
<p>10.textarea disabled</p>
<textarea disabled></textarea>
</div>
<div class="sample">
<select>
<option>11.セレクト</option>
</select>
</div>
<div class="sample">
<select disabled>
<option>12.セレクト(disabled)</option>
</select>
</div>
<div class="sample">
<details>
<summary>13.summary</summary>
<div>sample</div>
</details>
</div>
<div class="sample">
<p>14.area</p>
<map name="imgmap">
<area shape="rect" coords="0,0,400,267" href="#">
</map>
<img usemap="#imgmap" src="./img.jpg" width="400" height="267" alt="">
</div>
<div class="sample">
<p>15.area(hrefなし)</p>
<map name="imgmap2">
<area shape="rect" coords="0,0,400,267">
</map>
<img usemap="#imgmap2" src="./img.jpg" width="400" height="267" alt="">
</div>
<div class="sample">
<div tabindex="0">16.tabindex=0</div>
</div>
<div class="sample">
<div tabindex="-1">17tabindex=-1</div>
</div>
フォーカス可能な要素があるかを調べるデモページ
これで想定した動作にはなりましたが、フォーカス可能な要素の一覧は手動で洗い出しているので、抜けている要素がある可能性がある点ご了承ください。
コメントが承認されるまで時間がかかります。