Loop through childNodes

允我心安 提交于 2019-11-29 22:46:18

The variable children is a NodeList instance and NodeLists are not true Array and therefore they do not inherit the forEach method.

Also some browsers actually support it nodeList.forEach


ES5

You can use slice from Array to convert the NodeList into a proper Array.

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

You could also simply use call to invoke forEach and pass it the NodeList as context.

[].forEach.call(children, function(child) {});


ES6

You can use the from method to convert your NodeList into an Array.

var array = Array.from(children);

Or you can also use the spread syntax ... like so

let array = [ ...children ];


A hack that can be used is NodeList.prototype.forEach = Array.prototype.forEach and you can then use forEach with any NodeList without having to convert them each time.

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

See A comprehensive dive into NodeLists, Arrays, converting NodeLists and understanding the DOM for a good explanation and other ways to do it.

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);
}

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);
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.

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.)

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 );
        }
    };
}

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]
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!