DOMを再入門して理解を深める 【取得編2】

スポンサーリンク

どうも、イソップです。

DOMについての連載第4回目です。

今回も前回に引き続き、DOMを取得する方法について紹介します。

クラス名で取得する

クラス名での取得は、getElementsByClassName メソッドを使用します。
ページ中にある、指定されたクラス名のある要素を取得します。

例えば、ページ全体の box クラスが指定されている要素を取得するには、次のように記述します。

var boxes = document.getElementsByClassName('box');

タグの取得同様、DOMが取得されると、NodeListオブジェクトが返されます。
また、Elementオブジェクトからの実行も可能です。

<div id="page">
    <p class="box">foo</p>
    <p class="box">bar</p>
    <p class="box">baz</p>
</div>
<p class="box">abc</p>
<p class="box">def</p>

<script>
var page = document.getElementById('page');

// id="page" 内の.boxを取得
var pageBoxes = page.getElementsByClassName('box');
console.log(pageBoxes.length); // 3

// ページ全体の.boxを取得
var boxes = document.getElementsByClassName('box');
console.log(boxes.length); // 5
</script>

クラス名を複数指定することも可能です。
クラス名とクラス名は半角スペースで区切ります。

<div id="page">
    <p class="box">foo</p>
    <p class="box special">bar</p>
    <p class="box special">baz</p>
</div>

<script>
var page = document.getElementById('page');

// id="page" 内のpタグを取得
var pageBoxes = page.getElementsByClassName('box');
console.log(pageBoxes.length); // 3

// class="box special"を取得
var boxes = document.getElementsByClassName('box special');
console.log(boxes.length); // 2
</script>

この場合、取得される対象は、boxspecial 両方が指定された要素になります。
どちらかに該当しても、対象にはならないので注意してください。

Selectors API で取得する

DOMのAPIにも、jQueryのようにCSSセレクタを指定することで要素を取得することができる仕組みがあります。
それが Selectors API です。

Selectors APIには2つのメソッドがあります。

  • querySelector
    1つの要素を取得する。複数該当する場合は、始めの1つを取得する。
  • querySelectorAll
    複数の要素を取得する。

他のメソッドと比較してみると、次のようになります。

var page1 = document.getElementById('page');
var page2 = document.querySelector('#page')

var paragraph1 = document.getElementsByTagName('p');
var paragraph2 = document.querySelectorAll('p');

var pageBoxes1 = document.getElementsByClassName('box');
var pageBoxes2 = document.querySelectorAll('box');

var selectors = document.querySelectorAll('div#contents > article .article-body a[href=#]');

一目瞭然、今まで紹介してきたメソッドよりも、柔軟にDOMを取得することが出来ます。
ただし、他のメソッドに比べて、Selectors APIを使用するほうが取得のパフォーマンスは劣ります
以前、DOMの取得の際のパフォーマンスについて記事を書いていますので、参考にしてみてください。

また、Selectors APIで返されるのはNodeListオブジェクトではなく、StaticNodeListオブジェクトが返されます。
NodeListオブジェクトとStaticNodeListオブジェクトの違いは、オブジェクトに変更を加えた際に、HTMLに反映されるかどうかという違いです。

前回紹介した、ライブオブジェクトと関係している話ですが、
NodeListオブジェクトは取得後、オブジェクトに変更を加えればHTMLに反映されます。
しかし、StaticNodeListはオブジェクトに変更を加えても、HTMLに反映されません

var paragraph = document.querySelectorAll('p');
for (var i = 0; i < paragraph.length; i++) {
    paragraph[i].appendChild(document.createElement('span)); // Selectors APIでは無限ループにならない
}

他のメソッドではエラーだった、ループ処理ですが、Selectors APIを使うことで、正常に動作することから、
DOMツリーへの参照がされていないということがわかると思います。

この性質を理解しておくことで、思わぬアクシデントを回避できます。

次回に続きます。


イソップへのお悩み相談募集中

イソップに相談しませんか?

当ブログで紹介しているような、Web制作やフリーランスへの悩みをイソップに相談してみませんか?
回答できることがあれば記事の中でご紹介します。