Submitted by gwagner on
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
:
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:
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
method forEach
on the
DOM collection with the help of call
in the following way:
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:
- The most important one,
HTMLCollection
, represents a collection of HTML elements, typically obtained by retrieving HTML elements with one of the methodsgetElementsByTagName
,getElementsByClassName
orquerySelectorAll
. - A
DOMTokenList
represents a collection of items of an HTML attribute value list, such as the values of the HTMLclass
attribute. - 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). - 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 accessd 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.
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
, whcih returns an HTMLCollection
.