🔥
JavaScript / HTMLCollectionとNodeList
毎回調べてる気がする
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