このブログのはてなブックマーク数 このエントリーをはてなブックマークに追加

知らなきゃ絶対損するPCマル秘ワザ

知らなくて損したPC情報とかを分かりやすくメモする個人ブログ。
『月,水,金』の週3回更新!(予定)

このブログ内をキーワードで検索することもできます。
Loading



最新記事
  • やっぱり扇風機は「DCモーター」が良い? 実はそうでもないよ (05/25)
  • Firefox:レスポンシブデザインモードでダイアログが出ないバグ (05/23)
  • 「Windows+X」キーのPowerShell⇔コマンドプロンプト切り替え (05/21)
  • Firefox:プロファイルをコピーしたら一部アドオンが動作しない件 (05/18)
  • Windows:標準アプリだけでアラーム,タイマーをセットする方法 (05/16)
  • 管理人より
    2300万アクセス突破しました。ありがとうございます。

    JS:「querySelectorAll」は「getElementsBy」の簡略版ではない

    このエントリーをはてなブックマークに追加
    イメージ


    こんにちは、さち です。

    今回は、JavaScript の備忘録です。

    サイト上の要素を取得する時は「querySelectorAll」を使うと
    jQuery と似た CSS のような形式で記述できるのでとっても便利です。

    『これなら「getElementsBy」は要らないんじゃ?』
    と思ったんですが、そうもいかない決定的な違いが
    「getElementsBy」と「querySelectorAll」にはあるようです。




    「querySelectorAll」は CSS っぽい動作で簡単&便利

    例えば、下記のような HTML があります。
    「two」クラスを持つ <div> の中にある <li> をすべて取得してみます(11~14行目)。
    <div class="one">
    <ul>
    <li>1-1</li>
    <li>1-2</li>

    <li>1-X</li>
    </ul>
    </div>
    <div class="two">
    <ul>
    <li>2-1</li>
    <li>2-2</li>

    <li>2-X</li>
    </ul>
    </div>

    「getElementsBy」と「querySelectorAll」、それぞれで取得するとこんな感じ。
    //「getElementsBy」を使って取得
    var elm = document.getElementsByClassName('two')[0];
    var li = elm.getElementsByTagName('li');

    //「querySelectorAll」を使って取得
    var li = document.querySelectorAll('.two li');

    「querySelectorAll」は、CSS のような記述で取得できるので
    直感的かつ簡単に要素を取得できるという利点があります。
    CSS が書ける人にとっては神がかった機能です。

    『じゃあ、常に「querySelectorAll」使えばよくない?』と思うんですが
    残念ながら、それは無理です。
    両者では取得できるものが違うのです。




    「getElementsBy」と「querySelectorAll」の違い

    適当なクラスを「getElementsBy」と「querySelectorAll」それぞれで取得。
    取得した要素を調べてみます。
    var get = document.getElementsByClassName('class');
    var query = document.querySelectorAll('.class');

    console.log(get);// HTMLCollection []
    console.log(query);// NodeList []

    //console.log で種類が表示されない時はこちらで
    var get_type = Object.prototype.toString.call(get);
    var query_type = Object.prototype.toString.call(query);
    console.log(get_type);// [object HTMLCollection]
    console.log(query_type);// [object NodeList]

    「getElementsBy」は HTMLCollection(HTMLコレクション) を取得して
    「querySelectorAll」は NodeList(ノードリスト) を取得しています。

    両者ともに、同じ要素を取得しているはずなのに
    実際に受け取ったのは種類が異なるもの。
    これが、「getElementsBy」と「querySelectorAll」の決定的な違いです。

    何か挙動が違うっぽいぞということは分かりました。
    でも、HTMLCollection と NodeList で一体何がどう違うの……?




    「HTMLCollection」と「NodeList」の違い

    例として、下記のようなページを作ってみました。
    ボタンをクリックすると、リストに新しい <li> 要素を追加します。
    <ul>
    <li>かん</li>
    <li>かん</li>
    </ul>
    <button>「みかん」を追加</button>

    最初に、「getElementsBy」「querySelectorAll」でそれぞれ <li> を取得。
    「length」で要素の数を調べると、当然どちらも「2」です。
    では、ボタンをクリックして <li> を追加してから
    もう一度、それぞれで要素の数を調べるとどうなるでしょう?(15, 16行目)
    //li要素を取得
    var get = document.getElementsByTagName('li');
    var query = document.querySelectorAll('li');
    //取得したli要素の数
    console.log('get.length: ' + get.length);// get.length: 2
    console.log('query.length: ' + query.length);// query.length: 2

    //ボタンをクリックしたらリストに「みかん」を追加
    var ul = document.getElementsByTagName('ul')[0];
    var button = document.getElementsByTagName('button')[0];
    button.addEventListener('click', function() {
    var li = document.createElement('li');
    li.textContent = 'みかん';
    ul.appendChild(li);
    alert('get.length: ' + get.length);// ???
    alert('query.length: ' + query.length);// ???
    }, false);

    実際に、試してみて下さい。
    サンプル


    「get.length」は、追加した <li> の分だけ増えていくのに対して
    「query.length」は、ずっと「2」のままですね。

    「getElementsBy」で取得した
    「HTMLCollection」はリアルタイムで更新されるのに対して
    「querySelectorAll」で取得した
    「NodeList」は取得時点の状態のままということ。
    操作画面

    この特性から
    HTMLCollection は、動的な要素(=生きてる)
    NodeList は、静的な要素(=死んでる) などと言われています。

    つまり、常に最新の状態を取得したい要素は
    一度、「getElementsBy」で取得するだけで OK なわけです。

    記述形式の違いだけではなく、この特性の差を活かして使い分けたいですね。

    ちなみに、ボタンを押した後に
    get と query から最後尾の要素のテキストを取得すると
    get の方は、ちゃんと追加された「みかん」が出力されます。
    //最後の<li>要素のテキストを取得
    var get_text = get[get.length - 1].textContent;
    var query_text = query[query.length - 1].textContent;

    console.log(get_text);// みかん
    console.log(query_text);// かん

    HTMLCollection と NodeList は、どちらも配列に見えますが
    あくまで「配列のようなもの」であって、純粋な配列ではありません。
    そのため、配列のプロパティ,メソッド(forEachとか)はほぼ使えません。
    ややこしいんじゃあ……。




    まとめ

    それぞれのメソッドで何が返ってくるのか表にまとめました。
    表

    「getElementsBy」で取得すると
    HTMLCollection になるという感じで書いてきましたが
    「getElementsByName」は NodeList です。
    気をつけましょう。









    このエントリーをはてなブックマークに追加




    管理人だけが読めるコメントにする(返信はしません)
    【お知らせ】
    • コメントは承認制です。反映に時間がかかります。
    • Yahoo!BBはスパムコメントが多いため一部規制中です。
    • URLを含む投稿はできません。必要な場合は最初のhを削って下さい。
    • 記事に直接関係ない個人のトラブルにはお答えできません。
    • Android は使ったことがないので質問を頂いても答えられません。
    • その他詳細はこちら





    記事別の週間アクセス数ランキングです。こちらの記事もぜひ読んでみて下さい。

    2008-2018 知らなきゃ絶対損するPCマル秘ワザ  無断転載禁止

    ブログパーツ