What is the difference between a NodeList and an HTMLCollection

Dante Lombardi
3 min readApr 22, 2021

When using Javascript to manipulate the DOM there are a few ways to grab elements. Some of the most used are:

document.querySelectorAll();

or

document.getElementsByClassName();

let a = document.querySelectorAll(‘#elements’)a displays:NodeList[div.elements]let b = document.getElementsByClassName(‘elements’)b displays:HTMLCollection[div.elements]

querySelector returns a nodeList and getElements returns an HTMLCollection. So what is the difference between a nodeList and an HTMLCollection? Both are collections of DOM objects, one distinction is nodeList is static while HTMLCollection is live. In a “live” collection, changes to DOM are reflected in the collection object. A static collection changes in DOM do not update the collection.

HTMLCollections are array-like but they are not exactly arrays. They might look like arrays, and they have various numbered elements and can call some properties like .length on them but they do not have all the functionality that actual arrays do and you cannot call forEach() or other array methods on them.

NodeLists are also array-like, but you can call many more array methods on them.

Here is a list of HTMLCollection properties and methods:

HTMLCollection.length Returns the number of items in the collection.

HTMLCollection.item()Returns the specific node at the given zero-based index into the list. Returns null if the index is out of range.

HTMLCollection.namedItem()Returns the specific node whose ID or, as a fallback, name matches the string specified by name.

Here is a list of NodeList properties and methods:

NodeList.lengthThe number of nodes in the NodeList.

NodeList.item()Returns an item in the list by its index, or null if the index is out-of-bounds.

NodeList.entries()Returns an iterator, allowing code to go through all key/value pairs contained in the collection. (In this case, the keys are numbers starting from 0 and the values are nodes.)

NodeList.forEach()Executes a provided function once per NodeList element, passing the element as an argument to the function.

NodeList.keys()Returns an iterator, allowing code to go through all the keys of the key/value pairs contained in the collection. (In this case, the keys are numbers starting from 0.)

NodeList.values()Returns an iterator allowing code to go through all values (nodes) of the key/value pairs contained in the collection.

So how can you convert an HTMLCollection or NodeList to an Array? By using the spread operator!

const myArray = […document.getElementsByClassName(‘DOMElements’)]

const myArray = […document.querySelectorAll(‘#DOMElements’)]

Doing that would allow you to use all functionality just like any array.

It seems that some browsers are even confused about when to return nodeLists and HTMLCollections from different query calls.

Here’s what Mozilla says:

Note: While the W3C DOM 3 Core specification says elements is a NodeList that was simply because of a an attempt to have the “core” specification not depend on the “html” specification at that time. The DOM 4 draft says that elements is an HTMLCollection.

Gecko/Firefox currently returns a NodeList (Bug 162927) but starting with Gecko/Firefox 19, this method will return HTMLCollection (Bug 799464). Internet Explorer returns a HTMLCollection. WebKit returns a NodeList. Opera also returns a NodeList, but with a namedItem method implemented, which makes it similar to a HTMLCollection.

In conclusion, I’ve found that using querySelector to return nodeLists allows more flexibility on what to do with those objects. When in doubt I’ve preferred to use querySelector or to convert my collections to arrays.

--

--