DOMコレクション(NodeList, HTMLCollection)
DOM では、複数のノードや要素をまとめて扱うために**配列風(array-like)**のコレクション型が返されます。その代表が NodeList と HTMLCollection です。両者は「配列に似ている」が「配列ではない」点が重要で、length やインデックスアクセス(collection[0])はできますが、配列の全メソッドがそのまま使えるわけではありません。
共通の特徴
-
インデックスアクセス:
list[0],list.item(0) -
長さ取得:
list.length -
反復処理: どちらも
for...ofで反復可能(ブラウザの実装が十分に新しい前提) -
配列ではない: 直接
map/filter/reduceは使えません(必要ならArray.from(list)かスプレッド[...]で配列に変換)
NodeList とは
任意の Node を並べたコレクションです。Element だけでなく、Text や Comment などが含まれる場合があります。取得元によって**静的(static)かライブ(live)**かが異なる点が最大の特徴です。
代表的な取得方法
-
element.childNodes… ライブなNodeList(DOM変化を自動反映) -
document.querySelectorAll(selector)… 静的なNodeList(取得時点のスナップショット) -
document.getElementsByName(name)… 仕様上はNodeList(実装依存でライブのことが多い)
主な性質
-
含まれるノードの型: メソッド次第。
childNodesはTextなども含む。querySelectorAllは要素ノードのみ。 -
反復用メソッド: 近年の実装では
NodeList.prototype.forEachが利用可能。 -
ユースケース
-
CSS セレクタで一括取得 → 静的な一覧を安全に処理したいとき(
querySelectorAll) -
子ノードを低レベルに扱う(テキストノード含む)とき(
childNodes)
-
例
HTMLCollection とは
要素(Element)のみを集めたコレクションで、常にライブです。DOM が変化すると即座に内容が更新されます。フォームや画像などの「名前付きアクセス」を備えているのが特徴です。
代表的な取得方法
-
document.getElementsByTagName('div') -
document.getElementsByClassName('item') -
element.children(子の要素のみ。テキストは含まない) -
document.forms,document.imagesなど
主な性質
-
常にライブ: DOM の増減がそのまま反映。
-
要素のみ: テキストやコメントは含まない。
-
名前付きアクセス:
collection.namedItem('name')やcollection['loginForm'](一致するidまたはnameを持つ要素にアクセス。最初に見つかった1件) -
反復:
for...ofは可能だが、forEachはありません(配列化してからforEachを使うのが一般的)。
例
NodeList と HTMLCollection の違い(早見表)
| 観点 | NodeList | HTMLCollection |
|---|---|---|
| 含まれるノード | 任意の Node(取得元依存) | Element のみ |
| ライブ/静的 | 取得元により両方あり(childNodes=ライブ / querySelectorAll=静的) |
常にライブ |
| forEach | 使える(近年の実装) | なし(配列化して使用) |
| 名前付きアクセス | なし | namedItem / collection['nameOrId'] |
| 代表的生成元 | childNodes, querySelectorAll, getElementsByName |
getElementsBy*, children, forms, images |
実践ノウハウ/ベストプラクティス
-
「静的で安全」か「ライブで常に最新」かを選ぶ
-
DOM を変更しながら反復する処理では、ライブコレクションはバグの温床になりがちです。意図せず要素の増減でインデックスがずれ、取りこぼしや重複処理が起きます。
→ 変更しながら反復する場合は、最初に配列へコピーすると安全です。
-
-
配列メソッドを使いたいなら配列化する
-
子ノードの種類に注意
-
childNodes(NodeList)はテキストやコメントも含む。 -
children(HTMLCollection)は要素のみ。
要素だけ欲しいならchildrenまたはquerySelectorAllを使うと意図通りになります。
-
-
パフォーマンス配慮
-
ライブコレクションは参照するたびに最新状態を計算するコストが発生し得ます。サイズを何度も使うなら一度ローカル変数へ保存する、必要に応じて配列化する、
querySelectorAllの静的結果を用いるなどが有効です。
-
-
イベント付与の設計
-
ライブに増える要素へ都度リスナーを付けるより、親要素に一括でハンドラを置くイベントデリゲーションの方が堅牢なことが多いです。
-
典型パターン集
1) CSS セレクタで一括取得(静的)
2) 名前付きフォームへのアクセス(ライブ)
3) 要素だけの子一覧がほしい
4) NodeList を配列にして配列メソッドを使う
まとめ
-
NodeList は取得元によって静的/ライブが異なり、要素以外のノードを含むことがある汎用コレクション。
querySelectorAllは静的な NodeList を返すため、スナップショット処理に向く。 -
HTMLCollection は常にライブで要素のみ。
getElementsBy*系やchildren、formsなどが返し、名前付きアクセスが可能。 -
配列操作や DOM 変更を伴う反復では、配列化(
Array.from/ スプレッド)やイベントデリゲーションを取り入れると安全で効率的です。
ChatGPT5 生成日:2025/09/11