🔥

JavaScript / HTMLCollectionとNodeList

2025/01/13に公開

毎回調べてる気がする

React書くようになると直接的なDOM操作しなくなるので忘れてしまう。
というわけで、VanillaJSで徹底的におさらいしていこう。

HTMLCollectionとは

  • DOM操作を行う際に使用する配列風オブジェクト
  • 主に特定の要素を取得するメソッド(例: getElementsByTagName, getElementsByClassName)や、childrenプロパティを使用してアクセス可能。
  • 配列のようにインデックスが付与されているが、本物の配列ではないため、forEach()やfilter()などの配列メソッドは使用できない
  <div>div 1</div>
  <div>div 2</div>

  <script>
    const divs = document.getElementsByTagName('div');
    divs.forEach(divEl => {
      console.log(divEl)
      //  > Uncaught TypeError: divs.forEach is not a function
      //  > 訳)そんなメソッド、divsは持ってねぇよ
    });
  </script>
  • ライブコレクションであるため、DOMの変更が即座に反映される
<div>div 1</div>
<div>div 2</div>

<script>
const divs = document.getElementsByTagName('div');
divs[1].remove();
console.log(divs)
// > HTMLCollection [div]
// > 一つだけ取得
</script>

NodeListとは

  • 同じくDOM操作を行う際に使用する配列風オブジェクト。
  • 主にセレクタAPIであるquerySelectorAllメソッドやchildNodesプロパティでアクセス可能。
  • 基本的には配列メソッドは使用できないが、ES6以降ではforEach()が利用可能。
  <div>div 1</div>
  <div>div 2</div>

  <script>
    const divs = document.querySelectorAll('div');
    divs.forEach(divEl => {
      console.log(divEl)
      //  > <div>div 1</div>
      //  > <div>div 2</div>
    });
  </script>
  • 静的なコレクション であることが多く、DOMが変更されても内容は更新されない(一部のケースを除く)。
  <div>div 1</div>
  <div>div 2</div>

  <script>
    const divs = document.querySelectorAll('div');
    divs[1].remove();
    console.log(divs)
    //  > NodeList(2) [div, div]
    //  > 削除したはずなのに2つ取得
  </script>

補足

Node

  • DOMツリーを構成する要素。テキストやHTMLタグ、コメントが含まれる。
  • HTMLタグのみを表す場合はElementと呼ばれる。

childrenプロパティ

Nodeのうち、Elementが格納されているプロパティ

  <div id="container">
    テキストです
    <p>pタグ</p>
    <!-- コメントアウト -->
  </div>

  <script>
    const container = document.getElementById('container');
    console.log(container.children)
    // > HTMLCollection [p]
  </script>

childNodesプロパティ

HTMLタグやコメントなど、すべてのNodeが格納されているプロパティ

  <div id="container">
    テキストです
    <p>pタグ</p>
    <!-- コメントアウト -->
  </div>

  <script>
    const container = document.getElementById('container');
    console.log(container.childNodes)
    // > NodeList(5) [text, p, text, comment, text]
  </script>

まとめ

DOM要素を操作しようとしたら「あれ?」となってしまった経験は、JavaScriptを扱っていれば誰でもあるだろう。
それが配列操作の時だったり、HTMLタグを取得しようとしたら別のNodeだったりとか、それこそ人それぞれだと思う。
DOMに対する正しい知識があれば、これらのエラーにだってすぐに対処することができるはずだ。

Discussion