JavaScriptのHTMLCollectionとNodeListの違いをあらためて確認してみよう
2024年 5月20日 Posted 野々瀨(フロントエンドエンジニア)
JavaScriptで複数の要素を取得する際、getElementsByClassNameメソッドやquerySelectorAllメソッドとさまざまなメソッドを使用して取得します。戻ってくる値は、HTMLCollectionやNodeListというオブジェクトで返ってきます。しかし、同じまとまった形なのに使用するメソッドによっては、HTMLCollectionやNodeListと違いがあります。ここではどのような違いがあるのかを軽く説明したいと思います。
HTMLCollectionとは
HTMLCollectionは、複数の要素の集合体で、配列に似たオブジェクトです。また、一致した要素がDOM上に増加したり減少したりした場合にも動的に反映されます。
HTMLCollectionは次のメソッドやプロパティによって返されます。
document.getElementsByTagName
メソッドdocument.getElementsByClassName
メソッドdocument.getElementsByName
メソッドdocument.anchors
プロパティdocument.links
プロパティdocument.forms
プロパティdocument.images
プロパティElement.children
プロパティ
HTMLCollectionは次のプロパティやメソッドを持ちます。
プロパティ名 | 説明 |
---|---|
length | 要素の数を返す。 |
メソッド名 | 説明 |
---|---|
item | 第一引数で指定したインデックス番号に一致する要素を取得する。 |
namedItem | 第一引数で指定したname属性値に一致する要素を取得する。 |
参考リンク
- https://developer.mozilla.org/ja/docs/Web/API/HTMLCollection
- https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByTagName
- https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByClassName
- https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByName
- https://developer.mozilla.org/ja/docs/Web/API/Node/childNodes
NodeListとは
NodeListは、複数のノードの集合体であるオブジェクトです。ノードですので、タグ NodeListは動的に変化されるものと、静的に変化しないものの2種類があります。
NodeListは次のメソッドやプロパティによって返されます。
document.querySelectorAll
メソッド(静的で変化しない)Node.childNodes
プロパティ(動的に変化する)
NodeListは次のプロパティやメソッドを持ちます。
プロパティ名 | 説明 |
---|---|
length | ノードの数を返す。 |
メソッド名 | 説明 |
---|---|
item | 第一引数で指定したインデックス番号に一致する要素を取得する。 |
entries | キー(インデックス番号)とノードをペアとしたイテレーターを返す。 |
forEach | ノードを一つずつ繰り返して、第一引数で指定したコールバック関数を実行する。 |
keys | 全てのキー(インデックス番号)をイテレーターで返す。 |
values | 全てのノードをイテレーターで返す。 |
参考リンク
- https://developer.mozilla.org/ja/docs/Web/API/NodeList
- https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll
- https://developer.mozilla.org/ja/docs/Web/API/Element/children
得られる要素の違い
HTMLCollectionとNodeListとでは、得られる要素に違いがあります。HTMLCollectionはdivといった要素だけなのに対し、NodeListはテキストやdivといった要素を含むノード全てを対象にします。例えばElement.children
プロパティとNode.childNodes
プロパティで取得しますと、次のように戻り値が異なります。
<div class="foo">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Suscipit nesciunt perspiciatis ab!
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Explicabo aut consequatur voluptatem?</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque ut cupiditate modi.</p>
</div>
const parentElem = document.querySelector('.foo');
console.log(parentElem.children);
console.log(parentElem.childNodes);
繰り返すコードの違い
HTMLCollectionもNodeListもインデックス番号を持っていますので、配列のようにfor文を使用して繰り返すことができます。
const elems = document.getElementsByClassName('foo');
// for
for (let i = 0, len = elems.length; i < len; i++) {
console.log(elems[i]);
}
// for of
for (const elem of elems) {
console.log(elem);
}
const elems = document.querySelectorAll('.foo');
// for
for (let i = 0, len = elems.length; i < len; i++) {
console.log(elems[i]);
}
// for of
for (const elem of elems) {
console.log(elem);
}
NodeListでは、繰り返しが可能なforEachメソッドを持っています。
const elems = document.querySelectorAll('.foo');
elems.forEach(elem => {
console.log(elem);
});
このようにHTMLCollectionは繰り返すメソッドが用意されていませんが、NodeListはforEachというメソッドが用意されています。HTMLCollectionでもコールバック関数で繰り返しを行いたい場合は、次のようにArray.fromメソッドを使用し、配列に変換することで可能になります。
const elems = document.getElementsByClassName('foo');
Array.from(elems).forEach(elem => {
console.log(elem);
});
まとめ
まとめると、HTMLCollectionとNodeListとでは次のような違いがあります。
- 取得するためのメソッドやプロパティ
- 使用可能なメソッドやプロパティ
- 動的変化と静的変化
- 繰り返すためのコード