テーブルのtr内の th, td を丸っと処理したいみたいなケースを考えると、querySelectorAll('tr')
で tr を取得してループで回し、それぞれの tr で tr.childNodes
か tr.children
すれば th, td が取得できそうなイメージになります。
しかしquerySelectorAll
や Element.childNodes
、Element.children
などで取得される NodeList
, HTMLCollection
は .length
で要素数を取得したりはできるのですが、配列ではないので map
とか some
のような配列のメソッドが使えない場合があります。
NodeList は forEach でループ処理することができる
querySelectorAll
, Element.childNodes
で取得されるのは NodeList
。
NodeList
は forEach
を使うことができる。
const table = document.getElementById('#table'); table.querySelectorAll('tr').forEach((row) => { row.childNode.forEach((cell) => { // <th>, <td> の処理 }); });
forEach
以外の反復処理させるメソッドを使おうとするとエラーになる
table.querySelectorAll('tr').map((row) => {...}); // => Uncaught TypeError: table.querySelectorAll(...).map is not a function row.childNode.some((cell) => {...}); // => Uncaught TypeError: row.childNodes.some is not a function
HTMLCollection は forEach も使えない
getElementsByClassName
や Element.children
で取得されるのは HTMLCollection
。
HTMLCollection
は forEach
も使えない。
const table = document.getElementById('#table'); table.getElementByClassName('row').forEach((row) => { ... }); // => Uncaught TypeError: table.getElementsByClassName(...).forEach is not a function
NodeList, HTMLCollection で map
などの反復処理メソッドを使いたい場合
Array.from
や スプレッド構文で配列に変換すればOK
const table = document.getElementById('#table'); // Array.from で配列に変換 Array.from( table.querySelectorAll('tr') ).map((row) => { ... }); // [...] で配列に変換 [...table.children].filter((child) => { ... });
NodeList と HTMLCollection の違い
NodeList
も HTMLCollection
も参照している要素への変更は反映されるが、保持している要素数の増減に違いがある。
- NodeList は取得した時点の要素を保持する (静的)
- HTMLCollection は要素数に変化があれば増減後の要素になる (動的・参照みたいな感じ)
<ul id="list"> <li>list-1</li> <li>list-2</li> </ul>
const list = document.getElementById('list'); const nodeList = list.querySelectorAll('li'); // NodeList const collection = list.children; // HTMLCollection nodeList.length; // => 2 collection.length; // => 2 // 参照しているDOM要素の変更 nodeList[0].textContent += ' edited by NodeList'; collection[1].textContent += ' edited by HTMLCollection'; nodeList[1].textContent; // => list-2 edited by HTMLCollection collection[0].textContent; // => list-1 edited by NodeList // 要素数の変化 const li = document.createElement('li'); li.textContent = 'list-3'; list.appendChild(li); nodeList.length; // => 2 collection.length; // => 3
Sample
See the Pen nodeList vs HTMLCollection by KIKIKI (@chaika-design) on CodePen.
最近お仕事で全くコード書く機会がないから忘れる。
[参考]
- NodeList - Web API | MDN
- Document.querySelectorAll() - Web API | MDN
- Node.childNodes - Web API | MDN
- ParentNode.children - Web APIs | MDN
- Array.from() - JavaScript | MDN
- NodeListとHTMLCollectionも別物なので気を付けよう。(DOMおれおれAdvent Calendar 2015 – 13日目) | Ginpen.com

- アーティスト: アリス=紗良・オット
- 出版社/メーカー: Universal Music LLC
- 発売日: 2014/06/07
- メディア: MP3 ダウンロード
- この商品を含むブログを見る