querySelectorAll() - CSSセレクタで全ての要素を取得する方法

querySelectorAll()は、スタイルシートのセレクタを指定して、条件に合う全ての要素を取得するDocumentオブジェクトのメソッドです。CSSと同じルールで、複雑な条件を手軽に指定できるのが大きな魅力です。取得できる値はノードリストという、配列に似たオブジェクトです。このページでは配列と表現しています。このメソッドで取得するノードリストは生きていません。

説明

クラス名childの要素を取得して、elementsに代入する例です。

HTML

<p class="child">こんにちは、SYNCERです。</p>
<div class="parent">
	<p class="child">おはよう、SYNCERです。</p>
</div>
<p class="child">こんばんは、SYNCERです。</p>

JavaScript

var elements = document.querySelectorAll( ".child" ) ;

// elements[0] : <p class="child">こんにちは、SYNCERです。</p>
// elements[1] : <p class="child">おはよう、SYNCERです。</p>
// elements[2] : <p class="child">こんばんは、SYNCERです。</p>

存在しない場合は空の配列

条件に合う要素が存在しない場合、取得できるのは空の配列です。空の配列は、if文の条件式において真の値になるので、ご注意下さい。

HTML

<p class="syncer">こんにちは、SYNCERです。</p>
<p class="syncer">おはよう、SYNCERです。</p>
<p class="syncer">こんばんは、SYNCERです。</p>

JavaScript

var elements = document.querySelectorAll( ".syncer > .zvncer" ) ;

// 存在しないので、空の配列が返る
// elements : []

// 「要素が存在する時だけ」という条件分けをするには、[length]を参照すること
if( elements.length ) {
	// ...
}

// 空の配列は真の判定になるので、下記は条件分けにならない
if( elements ) {
	// ...
}

複数の条件を指定できる

カンマ(,)で区切って、複数の条件を指定することができます。指定した条件のいずれかに合う、全ての要素を取得します。取得できる(配列に代入される)順番は、ドキュメント上の順番通りです。

HTML

<p class="syncer1">こんにちは、SYNCERです。</p>
<div id="syncer">
	<p class="syncer2">おはよう、SYNCERです。</p>
</div>
<p class="syncer3">こんばんは、SYNCERです。</p>

JavaScript

// 3つの条件を指定して取得する
var elements = document.querySelectorAll( ".syncer3, .syncer1, #syncer .syncer2" ) ;

// 配列はDOMの順番通りとなる
// elements[0] : <p class="syncer1">こんにちは、SYNCERです。</p>
// elements[1] : <p class="syncer2">おはよう、SYNCERです。</p>
// elements[2] : <p class="syncer3">こんばんは、SYNCERです。</p>

取得した全ての要素に処理をする

取得した全ての要素に、一律で処理をしたい場合は、ループ処理をして下さい。オーソドックスなのは、for文です。

JavaScript

// 複数の要素を取得する
var elements = document.querySelectorAll( ".syncer3, .syncer1, #syncer .syncer2" ) ;

// 全ての要素に対して処理をする
for( var i=0,l=elements.length; l>i; i++ ) {
	// elements[i] = ...
}

// 下記の場合、処理の順番が逆になるが、上記より速い
for( var i=elements.length; i--; ) {
	// elements[i] = ...
}

ノードリストは死んでいる

querySelectorAll()で取得した値は、配列のようですが、正確にはノードリストというオブジェクトです。このノードリストは、死んでいます。「死んでいる」というのは、getElementsByClassName()などで取得できるノードリストが「生きている」と言われるのに対比させた表現です。

さて、生きているノードリストは、HTML上で要素に変更があった時、取得した値を代入してある変数の内容もそれに合わせて勝手に変わってしまいます。この性質を指して「生きている」と言います。対して、このquerySelectorAll()で取得したノードリストは、HTML上で要素に変更があっても、変数の内容はそれに合わせて変わりません。だから、スナップショットのように、記録的に利用することができます。

例えば、querySelectorAll()を使って、ノードリストを取得したとしましょう。

HTML

<span>こんにちは、SYNCERです。</span>
<span class="hoge">こんばんは、SYNCERです。</span>
<span id="hoge">おはよう、SYNCERです。</span>

JavaScript

// 要素を取得して、[elements]に代入する
var elements = document.querySelectorAll( "span" ) ;

// elements[0] : <span>こんにちは、SYNCERです。</span>
// elements[1] : <span class="hoge">こんばんは、SYNCERです。</span>
// elements[2] : <span id="hoge">おはよう、SYNCERです。</span>

その後、変数、elementsとは関係のないところで、HTML上の<span>こんにちは、SYNCERです。</span>が削除されたとします。次のようになりました。

HTML

<span class="hoge">こんばんは、SYNCERです。</span>
<span id="hoge">おはよう、SYNCERです。</span>

この時、生きているノードリストの場合、elementsの中身がそれに連動して勝手に変わってしまいます。ノードリストが常にHTMLドキュメントの最新の状態を反映しているわけです。

JavaScript

// [elements]の中から[0]が削除された
// elements[0] : <span class="hoge">こんばんは、SYNCERです。</span>
// elements[1] : <span id="hoge">おはよう、SYNCERです。</span>

対して、死んでいるノードリストの場合、elementsの中身が勝手に変わることがありません。ノードリストがHTMLドキュメントを反映していません。この違いを覚えておきましょう。

JavaScript

// [elements]の中身
// elements[0] : <span>こんにちは、SYNCERです。</span>
// elements[1] : <span class="hoge">こんばんは、SYNCERです。</span>
// elements[2] : <span id="hoge">おはよう、SYNCERです。</span>