Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Web Development Pitfall No.1: Confusing a DOM Collection with a JS Array

5.00/5 (5 votes)
10 Dec 2015CPOL3 min read 8.3K  
Don't confuse a DOM collection with a JS array: Array functions, such as the forEach looping method, cannot be applied to a DOM collection!

For more on JavaScript and the DOM, see web-engineering.info.

Summary

Don't confuse a DOM collection with a JS array: Array functions, such as the forEach looping method, cannot be applied to a DOM collection!

For instance, when you retrieve all rows of an HTML table element, you get an HTMLCollection, which is an array-like object, but not an instance of Array, and therefore the following code does not succeed because the Array method forEach is not defined for an HTMLCollection like myTableEl.rows:

JavaScript
var myTableEl = document.getElementById("myTableEl");
myTableEl.rows.forEach( function (row) {
  ... // process row
})

There are two solutions how to loop over a DOM collection like myTableEl.rows. Either by using an ordinary for loop, like so:

JavaScript
var myTableEl = document.getElementById("myTableEl");
var i=0, row=null;
for (i=0; i < myTableEl.rows.length; i++) {
  row = myTableEl.rows[i];
  ... // process row
}

or by invoking the Array.prototype.forEach method on the DOM collection with the help of call in the following way:

JavaScript
var myTableEl = document.getElementById("myTableEl");
Array.prototype.forEach.call( myTableEl.rows, function (row) {
  ... // process row
})

More on DOM Collections

Mozilla provides a pretty good overview of DOM interfaces, though not all methods have proper documentation yet. The ultimate reference is, of course, the hard-to-digest DOM4 specification, which comes in two forms: the W3C DOM4 spec and the WHATWG's DOM Living Standard

A DOM collection is an array-like object coll, the items of which can be accessed with the array index notation coll[i], and that has a length attribute such that a for loop can be used for iterating over it. There are 4 different types of DOM collections:

  1. The most important one, HTMLCollection, represents a collection of HTML elements, typically obtained by retrieving HTML elements with one of the methods getElementsByTagName, getElementsByClassName or querySelectorAll.
  2. A DOMTokenList represents a collection of items of an HTML attribute value list, such as the values of the HTML class attribute.
  3. A NamedNodeMap represents a collection of attributes (notice that, despite the historical name of this DOM collection type, attributes are no longer considered to be nodes in DOM4).
  4. A NodeList represents a collection of DOM nodes, which may be elements, plain text, comments or processing instructions.

All of these DOM collections have the item method in common, which implies that their items can be accessed with the array index notation. Two of them, HTMLCollection and NamedNodeMap, also have a (get)namedItem method, which implies that their items can be accessed with the key-value map notation. In the case of an HTMLCollection, the keys are provided by the elements' id attribute, while in the case of a NamedNodeMap, the keys are provided by the attribute names.

This is summarized in the following UML class diagram.

Image 1

Notice that a DOM element is a special type of DOM node (as expressed by the UML generalization arrow), so we can also use the attribute childNodes for an HTML element or SVG element for collecting all child nodes of it in the form of a NodeList, including child elements, but also comments, processing instructions, etc. However, when you only need to retrieve child elements, such as all child elements of a certain div, then you better use the method children, which returns an HTMLCollection.

You can find more useful materials on JavaScript and the DOM on web-engineering.info.

History

  • 10-Dec-2015: First version published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)