# Written by Claudio on Wednesday 18 November 2015 18:16, read 686 times.

I came across the need to iterate over the nodes returned by document.querySelectorAll() yesterday, in order to manipulate each of the nodes without mediation from any framework e.g. jQuery.

The return value of document.querySelectorAll() is a non-live NodeList. This means the contents of the collection won't change if the elements matching the selector change over time, so we must keep this in mind when making assumptions about the elements.

Unfortunately, this also means one can't invoke the usual Array prototype methods on NodeList, e.g. map() or forEach(). This forces us to a very verbose loop style like the following:


for (var i = 0; i < nodes.length; i++) {
  // do something with nodes[i]
}

Note that besides a property length, the NodeList has a method item(idx) that behaves the same as the square bracket item access, so the above is equivalent to:


for (var i = 0; i < nodes.length; i++) {
  // do something with nodes.item(i)
}

Psst: keep in mind the Array-like access nodes[i] and nodes.item(i) behave differently when trying to access an item outside the boundaries of the list. In that case, the former returns undefined, while the latter returns null. How cool... not!

Fortunately, ES6 iterators come to the rescue to simplify the syntax. Since a NodeList is an Iterable, we'll be able to use the for .. of loop. This will avoid iterating over other properties like length and item, and also guarantee that the items are visited in the right order.


for (var item of nodes) {
  // do something with item
}

This makes it for more concise and better readable code, allowing the reader to easily reason about the code.

Further Reading

Write a comment

An asterisk (*) denotes a required field. Markdown syntax allowed.