Element: querySelectorAll() メソッド
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Element
の querySelectorAll()
メソッドは、静的な(生きていない) NodeList
で、メソッド呼び出しの時点でそのオブジェクトの子孫にあたる要素のうち、一連のセレクターに一致するもののリストを返します。
構文
querySelectorAll(selectors)
引数
selectors
-
照合する 1 つまたは複数のセレクターを含む文字列です。この文字列は妥当な CSS セレクター文字列でなければなりません。そうでない場合は
SyntaxError
例外が発生します。HTML 仕様では、属性値が有効な CSS 識別子であることを求めていないことに注意してください。
class
またはid
属性の値が有効な CSS 識別子でない場合は、セレクターで使用する前に、値に対してCSS.escape()
で呼び出してエスケープするか、または「文字エスケープ」で記述されているテクニックのいずれかを使用してエスケープする必要があります。例えば、「属性値のエスケープ」を参照してください。なお、セレクターは
querySelectorAll()
が呼ばれた特定の要素だけでなく、文書全体に適用されることに注意してください。セレクターをquerySelectorAll()
が呼び出された要素に限定するには、セレクターの最初に:scope
擬似クラスを記述してください。セレクターのスコープの例を参照してください。
返値
例外
SyntaxError
DOMException
-
指定された
selectors
の構文が妥当ではない場合に発生します。
例
カスタムデータ値ですべての要素を取得
この例では、属性セレクターを使用して、 data-name
データ属性に "funnel-chart-percent" を含んでいる複数の属性を選択します。
<section class="box" id="sect1">
<div data-name="funnel-chart-percent1">10.900%</div>
<div data-name="funnel-chart-percent2">3700.00%</div>
<div data-name="funnel-chart-percent3">0.00%</div>
</section>
const refs = [
...document.querySelectorAll(`[data-name*="funnel-chart-percent"]`),
];
一致するもののリストの入手
NodeList
で "myBox"
要素の中にあるすべての <p>
要素を取得するには、次のようにします。
const matches = myBox.querySelectorAll("p");
次の例では、文書内にあるすべての <div>
要素のうち、 note
または alert
のいずれかのクラスを持つもののリストを返します。
const matches = myBox.querySelectorAll("div.note, div.alert");
ここでは、文書の <p>
要素のうち、直接の親要素が <div>
の "highlighted"
クラスのものであり、それが ID が "test"
であるコンテナーの中にあるものの一覧を取得します。
const container = document.querySelector("#test");
const matches = container.querySelectorAll("div.highlighted > p");
次の例では属性セレクターを使用して、文書内の <iframe>
要素のうち "data-src"
という名前の属性を持つもののリストを返します。
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);
});
メモ: NodeList
は、厳密には配列ではありません。つまり、slice
、some
、map
などの配列メソッドを持っていません。これを配列に変換するには、 Array.from(nodeList)
と実行してください。
セレクターのスコープ
querySelectorAll()
メソッドは、セレクターを文書全体に適用します。このメソッドが呼び出された要素だけのスコープにするわけではありません。セレクターのスコープを設定するには、セレクター文字列の先頭に :scope
擬似クラスを置いてください。
HTML
この例では、HTML に次のものが含まれています。
- 2 つのボタン:
#select
および#select-scope
- 3 重に入れ子になった
<div>
要素:#outer
,#subject
,#inner
- この例が出力に使用する
<pre>
要素
<button id="select">Select</button>
<button id="select-scope">Select with :scope</button>
<div id="outer">
#outer
<div id="subject">
#subject
<div id="inner">#inner</div>
</div>
</div>
<pre id="output"></pre>
JavaScript
JavaScript では、まず #subject
要素を選択します。
select
ボタンが押されたら、セレクター文字列として "#outer #inner"
を渡して #subject
に対して querySelectorAll()
を呼び出します。
#select-scope
ボタンが押されたら、再び querySelectorAll()
を #subject
に対して呼び出しますが、この時は ":scope #outer #inner"
をセレクター文字列として渡します。
const subject = document.querySelector("#subject");
const select = document.querySelector("#select");
select.addEventListener("click", () => {
const selected = subject.querySelectorAll("#outer #inner");
output.textContent = `Selection count: ${selected.length}`;
});
const selectScope = document.querySelector("#select-scope");
selectScope.addEventListener("click", () => {
const selected = subject.querySelectorAll(":scope #outer #inner");
output.textContent = `Selection count: ${selected.length}`;
});
結果
"Select" を押すと、セレクターは inner
という ID を持つ要素のうち、outer
という ID を持つ祖先を持つ要素をすべて選択します。なお、#outer
は #subject
要素の外側にあるにもかかわらず、選択で使用されるため、#inner
要素が見つかります。
"Select with :scope" を押すと、:scope
擬似クラスがセレクターのスコープを #subject
に制限するので、セレクターの照合では #outer
は使われず、#inner
要素は見つかりません。
属性値のエスケープ
例えば、 HTML 文書の中の id
が有効な CSS 識別子ではないものが含まれている場合、 querySelector()
で使用する前に属性値をエスケープする必要があります。
HTML
以下のコードは、 <div>
要素には id
として "this?element"
が設定されており、これは有効な CSS 識別子ではありません。 "?"
文字が CSS 識別子に許可されていないためです。
ここには 3 つのボタンがあり、エラーを出力するために <pre>
要素があります。
<div id="container">
<div id="this?element"></div>
</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>
を選択して、その背景色をランダムな値に設定しようとします。
- 最初のボタンは
"this?element"
の値を直接使用しています。 - 2 つ目のボタンは
CSS.escape()
で値をエスケープします。 - 3 つ目のボタンはバックスラッシュを用いて、明示的に
"?"
文字をエスケープしています。なお、もう一つのバックスラッシュを用いて、"\\?"
のようにバックスラッシュ自体をエスケープする必要があります。
const container = document.querySelector("#container");
const log = document.querySelector("#log");
function random(number) {
return Math.floor(Math.random() * number);
}
function setBackgroundColor(id) {
log.textContent = "";
try {
const elements = container.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");
});
結果
最初のボタンをクリックするとエラーが返されますが、 2 つ目と 3 つ目のボタンは正規に動作します。
仕様書
Specification |
---|
DOM # ref-for-dom-parentnode-queryselectorall① |
ブラウザーの互換性
Report problems with this compatibility data on GitHubdesktop | mobile | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
querySelectorAll |
Legend
Tip: you can click/tap on a cell for more information.
- Full support
- Full support