[javascript] Loop through childNodes

I'm trying to loop through childNodes like this:

var children = element.childNodes;
children.forEach(function(item){
    console.log(item);
});

However, it output Uncaught TypeError: undefined is not a function due to forEach function. I also try to use children instead of childNodes but nothing changed.

Does anybody know what's going on?

This question is related to javascript loops children

The answer is


I'm very late to the party, but since element.lastChild.nextSibling === null, the following seems like the most straightforward option to me:

for(var child=element.firstChild; child!==null; child=child.nextSibling) {
    console.log(child);
}

Couldn't resist to add another method, using childElementCount. It returns the number of child element nodes from a given parent, so you can loop over it.

for(var i=0, len = parent.childElementCount ; i < len; ++i){
    ... do something with parent.children[i]
    }

If you do a lot of this sort of thing then it might be worth defining the function for yourself.

if (typeof NodeList.prototype.forEach == "undefined"){
    NodeList.prototype.forEach = function (cb){
        for (var i=0; i < this.length; i++) {
            var node = this[i];
            cb( node, i );
        }
    };
}

Here is how you can do it with for-in loop.

var children = element.childNodes;

for(child in children){
    console.log(children[child]);
}

Try with for loop. It gives error in forEach because it is a collection of nodes nodelist.

Or this should convert node-list to array

function toArray(obj) {
  var array = [];
  for (var i = 0; i < obj.length; i++) { 
    array[i] = obj[i];
  }
return array;
}

Or you can use this

var array = Array.prototype.slice.call(obj);

Try this [reverse order traversal]:

var childs = document.getElementById('parent').childNodes;
var len = childs.length;
if(len --) do {
    console.log('node: ', childs[len]);
} while(len --);

OR [in order traversal]

var childs = document.getElementById('parent').childNodes;
var len = childs.length, i = -1;
if(++i < len) do {
    console.log('node: ', childs[i]);
} while(++i < len);

Here is a functional ES6 way of iterating over a NodeList. This method uses the Array's forEach like so:

Array.prototype.forEach.call(element.childNodes, f)

Where f is the iterator function that receives a child nodes as it's first parameter and the index as the second.

If you need to iterate over NodeLists more than once you could create a small functional utility method out of this:

const forEach = f => x => Array.prototype.forEach.call(x, f);

// For example, to log all child nodes
forEach((item) => { console.log(item); })(element.childNodes)

// The functional forEach is handy as you can easily created curried functions
const logChildren = forEach((childNode) => { console.log(childNode); })
logChildren(elementA.childNodes)
logChildren(elementB.childNodes)

(You can do the same trick for map() and other Array functions.)


const results = Array.from(myNodeList.values()).map(parser_item);

NodeList is not Array but NodeList.values() return a Array Iterator, so can convert it to Array.