Document: querySelectorAll() メソッド
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
Document の querySelectorAll() メソッドは、指定された CSS セレクターに一致する文書中の要素のリストを示す静的な(生きていない)NodeList を返します。
構文
querySelectorAll(selectors)
引数
返値
ライブではない NodeList で、指定されたセレクターの少なくとも 1 つに一致する要素ごとに Element を一つずつ含みます。または一致するものがなければ空の NodeList です。要素は文書内の順序で並んでいます。つまり、親要素が子要素より先に、先に定義された兄弟要素が後に定義された兄弟要素より先に配置されます。
メモ:
指定された selectors が CSS 擬似要素を含む場合、返されるリストは常に空になります。
例外
SyntaxErrorDOMException-
指定された
selectorsの構文が妥当ではない場合です。
例
>一致するもののリストの入手
文書内のすべての <p> 要素の NodeList を入手します。
const matches = document.querySelectorAll("p");
次の例では、文書内にあるすべての <div> 要素のうち、 note または alert のいずれかのクラスを持つものリストを返します。
const matches = document.querySelectorAll("div.note, div.alert");
次に、 <p> 要素ののうち直近の親要素が test という ID を持つコンテナー内に位置し、直接の親要素が highlighted クラスを持つ <div> であるリストを取得します。
const container = document.querySelector("#test");
const matches = container.querySelectorAll("div.highlighted > p");
次の例では属性セレクターを使用しており、 data-src という名前の属性を持つ、文書内の <iframe> 要素のリストを返します。
const matches = document.querySelectorAll("iframe[data-src]");
次の例では、ID が user-list の要素の中にあり、data-active 属性を持ち、その値が 1 であるリスト項目のリストを返すため、属性セレクターが使用されています。
const container = document.querySelector("#user-list");
const matches = container.querySelectorAll("li[data-active='1']");
一致したリストへのアクセス
いったん、一致した要素の NodeList が返されると、それをちょうど配列のように見ることができます。配列が空である (length プロパティが 0 である) 場合は、一致がなかったということです。
それ以外の場合は、単純に標準の配列表記を使って、リストの内容にアクセスすることができます。次のように、任意の一般的なループ処理を使うことができます。
const highlightedItems = userList.querySelectorAll(".highlighted");
highlightedItems.forEach((userItem) => {
deleteUser(userItem);
});
属性値のエスケープ
この例は、HTML 文書に id として有効な CSS 識別子ではないものが含まれている場合、querySelector() でそれを使用する前に、属性値をエスケープする必要があることを示しています。
HTML
以下のコードでは、<div> 要素の id が "this?element" となっていますが、CSS の識別子では "?" 文字を使用することができないため、これは有効な CSS 識別子ではありません。
また、3 つのボタンと、エラーをログ出力するための <pre> 要素があります。
<div id="this?element"></div>
<button id="no-escape">エスケープなし</button>
<button id="css-escape">CSS.escape()</button>
<button id="manual-escape">手動エスケープ</button>
<pre id="log"></pre>
CSS
div {
background-color: blue;
margin: 1rem 0;
height: 100px;
width: 200px;
}
JavaScript
3 つのボタンはすべて、クリックされると <div> を選択しようとし、その後、その背景色をランダムな値に設定します。
- 1 つ目のボタンは、
"this?element"を直接使用しています。 - 2 つ目のボタンは、
CSS.escape()を使用して値をスケープしています。 - 3 つ目のボタンは、バックスラッシュを使用して
"?"の文字を明示的にエスケープしています。なお、バックスラッシュ自体も、同様に別のバックスラッシュを使用して"\\?"のようにエスケープしなければなりません。
const log = document.querySelector("#log");
function random(number) {
return Math.floor(Math.random() * number);
}
function setBackgroundColor(id) {
log.textContent = "";
try {
const elements = document.querySelectorAll(`#${id}`);
const randomColor = `rgb(${random(255)} ${random(255)} ${random(255)})`;
elements[0].style.backgroundColor = randomColor;
} catch (e) {
log.textContent = e;
}
}
document.querySelector("#no-escape").addEventListener("click", () => {
setBackgroundColor("this?element");
});
document.querySelector("#css-escape").addEventListener("click", () => {
setBackgroundColor(CSS.escape("this?element"));
});
document.querySelector("#manual-escape").addEventListener("click", () => {
setBackgroundColor("this\\?element");
});
結果
1 つ目のボタンをクリックするとエラーが発生しますが、2 つ目と 3 つ目のボタンは正常に動作します。
仕様書
| Specification |
|---|
| DOM> # ref-for-dom-parentnode-queryselectorall①> |