Jump to the content

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

JavaScript

    どうも、イソップです。

    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ツリーへの参照がされていないということがわかると思います。

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

    次回に続きます。

    注目記事

    最近の記事

    ぼくが書いてます

    フロントエンドエンジニア

    イソップ

    ページの先頭に戻る

    Search results

    ×