NodeList は「querySelectorAll が返してくる“要素の集まり”」
まず前提からいきます。document.querySelectorAll() を使うと、複数の要素が一度に取れます。
const items = document.querySelectorAll(".item");
console.log(items);
JavaScriptこの items の正体が NodeList です。
見た目は配列っぽいけれど、
「完全な配列ではない “配列風オブジェクト”」というのがポイントです。
ここをちゃんと理解しておくと、
「for で回す」「forEach を使う」「配列に変換する」などの判断がスムーズになります。
NodeList の基本的な性質を押さえる
配列っぽいけど配列ではない
NodeList は、インデックスでアクセスできます。
const items = document.querySelectorAll(".item");
console.log(items[0]); // 最初の要素
console.log(items.length); // 要素数
JavaScriptここまでは配列と同じです。
ただし、map や filter などの「配列メソッド」は、そのままでは使えません。
items.map(...); // エラーになる(NodeList には map がない)
JavaScriptこの「配列っぽいけど配列じゃない」という中途半端さが、
初心者をよく混乱させます。
forEach は使える(現代ブラウザ)
幸い、今どきのブラウザでは NodeList にも forEach が生えています。
items.forEach((item, index) => {
console.log(index, item);
});
JavaScript「全部に同じ処理をしたい」というときは、
まず forEach を思い出してOKです。
例題:複数のボタンに同じイベントを付ける
HTML
<button class="color-btn" data-color="red">赤</button>
<button class="color-btn" data-color="green">緑</button>
<button class="color-btn" data-color="blue">青</button>
<div id="box" style="width:100px;height:100px;background:gray;"></div>
JavaScript
const buttons = document.querySelectorAll(".color-btn");
const box = document.querySelector("#box");
buttons.forEach((btn) => {
btn.addEventListener("click", () => {
const color = btn.dataset.color;
box.style.backgroundColor = color;
});
});
JavaScriptここでやっていることは、
querySelectorAll で .color-btn を全部取る
NodeList に対して forEach で 1 個ずつ処理を書く
各ボタンの data-color を読んで、box の色を変える
という流れです。
「複数の要素に同じ処理を付ける」というのは、
NodeList の一番典型的な使い方です。
重要ポイント①:NodeList を「配列に変換する」テクニック
Array.from を使う
配列メソッド(map, filter, reduce など)を使いたいときは、
NodeList を配列に変換します。
const items = document.querySelectorAll(".item");
const arr = Array.from(items);
const texts = arr.map(el => el.textContent);
console.log(texts);
JavaScriptArray.from(NodeList) で、
「本物の配列」に変換できる、というのを覚えておくと便利です。
スプレッド構文でも変換できる
const items = document.querySelectorAll(".item");
const arr = [...items];
JavaScriptこの書き方もよく使われます。
見た目がスッキリしていて、個人的にはかなり好きなパターンです。
重要ポイント②:静的 NodeList と「ライブ」なコレクションの違い
querySelectorAll の NodeList は「静的」
document.querySelectorAll() が返す NodeList は、
静的(static) です。
つまり、あとから DOM が変わっても、
その NodeList の中身は自動では更新されません。
const items = document.querySelectorAll(".item");
console.log(items.length); // 3 とする
const newItem = document.createElement("div");
newItem.className = "item";
document.body.appendChild(newItem);
console.log(items.length); // 3 のまま(増えない)
JavaScript「最初に取った時点のスナップショット」として扱うイメージです。
getElementsByClassName などは「ライブ」
一方で、document.getElementsByClassName() などが返すのはHTMLCollection という別の型で、こちらは ライブ(live) です。
DOM に要素を追加・削除すると、
そのコレクションの中身も自動で変わります。
NodeList と HTMLCollection の違いは少しややこしいですが、
初心者のうちは、
querySelectorAll → NodeList(静的)getElementsBy◯◯ → HTMLCollection(ライブ)
くらいの理解で十分です。
「とりあえず querySelectorAll を使う」
という癖をつけておけば、大きく困ることはありません。
例題:NodeList を配列に変換して map / filter を使う
HTML
<ul>
<li class="item">りんご</li>
<li class="item">バナナ</li>
<li class="item">みかん</li>
</ul>
JavaScript
const nodeList = document.querySelectorAll(".item");
// 配列に変換
const items = Array.from(nodeList);
// テキストだけの配列にする
const texts = items.map(li => li.textContent);
console.log(texts); // ["りんご", "バナナ", "みかん"]
// 「ん」が含まれるものだけに絞る
const filtered = items.filter(li => li.textContent.includes("ん"));
console.log(filtered); // りんご, みかん の li 要素
JavaScriptここでのポイントは、
NodeList のままでは map / filter が使えない
Array.from で配列に変換すると、配列メソッドが全部使える
という流れです。
「NodeList → 配列 → map / filter」というパターンは、
DOM 操作でかなり頻出します。
重要ポイント③:for / for…of / forEach の使い分け
forEach:一番読みやすい「全要素に同じ処理」
nodeList.forEach((node, index) => {
// 処理
});
JavaScriptシンプルで読みやすく、
副作用(イベント登録・スタイル変更など)を書くのに向いています。
for…of:シンプルなループ構文として
for (const node of nodeList) {
// 処理
}
JavaScriptfor...of は、
NodeList のような「反復可能オブジェクト」に対して使えます。
index が不要で、
「とにかく全部回したい」だけなら、forEach と同じくらい読みやすいです。
古典的な for ループ
for (let i = 0; i < nodeList.length; i++) {
const node = nodeList[i];
// 処理
}
JavaScript昔からある書き方で、
今でもパフォーマンス重視の場面などでは使われます。
初心者のうちは、
「まずは forEach か for…of」
「配列メソッドを使いたくなったら Array.from で配列にする」
くらいの感覚で十分です。
例題:チェックボックスの選択状態をまとめて取得する
HTML
<label><input type="checkbox" name="fruit" value="apple"> りんご</label>
<label><input type="checkbox" name="fruit" value="banana"> バナナ</label>
<label><input type="checkbox" name="fruit" value="orange"> みかん</label>
<button id="show">選択中を表示</button>
JavaScript
const checkboxes = document.querySelectorAll('input[name="fruit"]');
const showBtn = document.querySelector("#show");
showBtn.addEventListener("click", () => {
const checked = Array.from(checkboxes)
.filter(cb => cb.checked)
.map(cb => cb.value);
console.log("選択中:", checked);
});
JavaScriptここでの流れは、
NodeList を Array.from で配列に変換
filter で checked なものだけに絞る
map で value の配列にする
という、NodeList 操作の「王道コンボ」です。
このパターンが自然に書けるようになると、
フォーム操作や UI 制御が一気に楽になります。
初心者として NodeList 操作で本当に掴んでほしいこと
querySelectorAll が返すのは NodeList(配列っぽいけど配列ではない)
NodeList には length とインデックスアクセスがあり、forEach も使える
配列メソッドを使いたいときは Array.from や […nodeList] で配列に変換する
querySelectorAll の NodeList は「静的」で、あとから DOM が変わっても自動更新されない
「複数要素に同じ処理をする」場面では、NodeList+forEach が基本パターンになる
まずは、
.item を全部取ってきて、
forEach で背景色を変える
Array.from で配列にして、textContent の配列を作る
といった小さな練習をしてみてください。
「単体の要素」ではなく、
「要素の集まりをまとめて扱う」感覚 が身につくと、
NodeList はただの返り値ではなく、
UI 全体をコントロールするための、頼れる入り口に見えてきます。
