Pourquoi tout ne fonctionne-t-il pas pour les enfants?

J'ai un <div> avec un enfant <div> . Par exemple

 <div id="niceParent"> <div></div> <div></div> <div></div> <div></div> </div> 

J'ai essayé de les traverser avec la fonction forEach , car je pensais que document.getElementById("niceParent").children sont un tableau, car je peux accéder aux éléments avec

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

D'où j'ai essayé

 document.getElementById("niceParent").children.forEach(function(entry) { console.log(entry); }); 

Qui ne fonctionne pas. Je reçois

 TypeError: document.getElementById(...).children.forEach is not a function 

Comme solution de contournement, je l'ai également essayé avec une boucle beaucoup plus compliquée pour for..in boucle:

 for (var i in document.getElementById("niceParent").children) { if (document.getElementById("niceParent").children[i].nodeType == 1) console.log(document.getElementById("niceParent").children[i]); } 

Qui a fonctionné comme prévu.

Pourquoi?

Parce que .children contient un NodeList [MDN] , pas un tableau. Un objet NodeList est un objet en forme de tableau , qui expose une propriété .length et a des propriétés numériques, tout comme des tableaux, mais il ne hérite pas de Array.prototype et n'est donc pas un tableau.

Vous pouvez le convertir en un tableau en utilisant Array.prototype.slice :

 var children = [].slice.call(document.getElementById(...).children); 

ECMAScript 6 introduit une nouvelle API pour convertir des itérateurs et des objets similaires à des matrices en tableaux réels: Array.from [MDN] . Utilisez-le si possible car cela rend l'intention beaucoup plus claire.

 var children = Array.from(document.getElementById(...).children); 

Element.children n'est pas un tableau. C'est un objet DOM appelé NodeList . Ceux-ci n'ont pas les fonctions d'un tableau (bien qu'ils possèdent la propriété length ).

Pour le faire passer, vous devrez le convertir en un tableau, que vous pouvez faire en utilisant Array.prototype.slice :

 var children = Array.prototype.slice.call(document.getElementById("niceParent").children); children.forEach(... 

Vous pouvez également le faire:

 NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 

Et après cela, vous pouvez appeler pour tout sur votre collection:

 document.getElementById("niceParent").children.forEach(...)