I have a <div>
with some child <div>
in it. E.g.
<div id="niceParent">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
I tried to loop through them with the forEach
function, because I thought that document.getElementById("niceParent").children
is an array, as I can access the elements with
console.log(document.getElementById("niceParent").children[1]);
console.log(document.getElementById("niceParent").children[2]);
console.log(document.getElementById("niceParent").children[3]);
console.log(document.getElementById("niceParent").children[4]);
Hence I tried
document.getElementById("niceParent").children.forEach(function(entry) {
console.log(entry);
});
which is not working. I get
TypeError: document.getElementById(...).children.forEach is not a function
As a workaround I also tried it with a—much more complicated—for..in
loop:
for (var i in document.getElementById("niceParent").children) {
if (document.getElementById("niceParent").children[i].nodeType == 1) console.log(document.getElementById("niceParent").children[i]);
}
which worked as expected.
Why?
Because .children
contains a NodeList
[MDN], not an array. A NodeList
object is an array-like object, which exposes a .length
property and has numeric properties, just like arrays, but it does not inherit from Array.prototype
and thus is not an array.
You can convert it to an array using Array.prototype.slice
:
var children = [].slice.call(document.getElementById(...).children);
ECMAScript 6 introduces a new API for converting iterators and array-like objects to real arrays: Array.from
[MDN]. Use that if possible since it makes the intent much clearer.
var children = Array.from(document.getElementById(...).children);
Element.children
is not an array. It is an object called an HTMLCollection
. These do not have an array’s methods (though they do have the length
property).
To loop through it, you'll have to convert it into an array, which you can do using Array.prototype.slice
:
var children = Array.prototype.slice.call(document.getElementById("niceParent").children);
children.forEach(…);
You can also do this:
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
And after this you can call forEach on your collection:
document.getElementById("niceParent").children.forEach(...)
A cleaner and more modern way to convert a HTMLCollection
like .children
to an array to use forEach()
(or map()
, etc.) is to use the spread synthax ...
in an array []
.
var children = [...document.getElementById('x').children)];
for example:
[...document.getElementById('x').children)].forEach(child => console.log(child))
This is an es6 feature. It will work on all modern browser.