2015/04/10

getElementsByTagNameとquerySelectorAllの違い

photo by Tim Johnson

querySelectorAllという存在を知り、さっそくToDoアプリでgetElementsByTagNameを使っているところを書き換えようとしたとき、問題が発生した。

それは、以下の違いによるものだった。
  • getElementsByTagName : 動的なNodeList
  • querySelectorAll : 静的なNodeList


追記:2015/04/25 16:40
コメントで指摘していただいた箇所について追記する。ご指摘ありがとうございました!
※ コメント通知で気づいた時にはすでに削除?されていたっぽいですが

getElementByTagName について

ゆくゆくは、NodeListではなくHTMLCollection が返ってくるようになる。
どちらもcollectionに変わりないが、メソッドが少し違うので注意。



具体例をあげて違いをまとめていく。
ついでにquerySelectorAllの代替案として、ID指定のgetElementsByTagNameについても載せておく。



HTML


以降、このHTMLをもとにして進めていく。



getElementsByTagName


getElementsByTagNameは、指定したタグ名を持つリスト(NodeList)を取得するメソッド。

しかし、このままではHTMLにある全てのタグ要素を取得してしまう。
それを解決するために、querySelectorAllを使用する。

querySelectorAll


querySelectorAllは、CSSセレクタにマッチする要素のリスト(NodeList)を取得するメソッド。
jQueryで「$(‘#id > li’)」みたいに書く感覚だ。


うまい具合にID指定をしつつ、LI要素を取得することができる。
しかし、前述の通り、querySelectorAllは「静的なNodeList」のため、取得した時点でのNodeListを保持してしまう。
そのため、サンプルにあるように、要素を追加してもlengthが1のままになってしまう。

IDを指定したい。でも動的なNodeListが欲しいという場合の対応法について、次で説明する。


ID指定のgetElementsByTagName


IDを指定しつつ、動的なNodeListを取得したい場合は、以下のようにすればよい。


ちょっと長くなってしまうが、getElementByIdとgetElementsByTagNameを併用すればよい。
他にもgetElementsByClassNameなどとも併用できる。




以上

written by @bc_rikko

2 件のコメント :

  1. HTMLのcollectionでハマりやすいところを捉えたいい記事だと思います。
    ただ、一つ気になるのは、動的なNodeListと静的なNodeListとされている点です。
    確かに、NodeListには静的なものと動的なものが有ります。
    ->https://developer.mozilla.org/ja/docs/Web/API/NodeList
    childNodesなどが動的なもの、querySelectorAllなどが静的なものとされています。
    ただ、getElementsByTagNameで取得したものは、NodeListではなく、HTMLCollectionです。
    MDNの日本語版やDOM3ではNodeListが返ってくることになっていますが、
    MDNのUS版や、DOM4では、HTMLCollectionが返ることになっています。
    ->http://www.w3.org/TR/domcore/
    FirefoxやChrome等のブラウザの実装もそれに追従しています。
    NodeListもHTMLCollectionもcollectionには変わりないのですが、メソッドが少し違うという点があります。
    どちらもArray.from等で配列化してしまえば意味ないんですけどね。参考までに。

    返信削除
    返信
    1. ご指摘ありがとうございます!
      内容は、本文に追記いたしました。

      ちょっとした手違いでコメントを非公開にしてしまい、今まで削除されたものだと勘違いしておりました。
      申し訳ございません。

      削除