web-dev-qa-db-fra.com

Boucle à travers les childNodes

J'essaie de parcourir en boucle les childNodes comme ceci:

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

Cependant, il a sorti Uncaught TypeError: undefined is not a function en raison de la fonction forEach. J'essaie aussi d'utiliser children au lieu de childNodes mais rien n'a changé.

Est-ce que quelqu'un sait ce qui se passe?

63
user3828771

La variable children est une instance NodeList et NodeLists ne sont pas vrais Array et par conséquent n'hérite pas de la méthode forEach .

De plus, certains navigateurs le supportent réellement nodeList.forEach


ES5

Vous pouvez utiliser slice de Array pour convertir le NodeList en un Array correct.

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

Vous pouvez aussi simplement utiliser call pour appeler forEach et lui transmettre le NodeList comme contexte.

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


ES6

Vous pouvez utiliser la méthode from pour convertir votre NodeList en Array.

var array = Array.from(children);

Ou vous pouvez également utiliser le syntaxe de propagation ... comme si

let array = [ ...children ];


Un hack qui peut être utilisé est NodeList.prototype.forEach = Array.prototype.forEach Et vous pouvez ensuite utiliser forEach avec n'importe quel NodeList sans avoir à les convertir à chaque fois.

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

Voir ne plongée complète dans NodeLists, Arrays, conversion de NodeLists et compréhension du DOM pour une bonne explication et d'autres moyens de le faire.

97
GillesC

Je suis très en retard à la fête, mais depuis element.lastChild.nextSibling === null, l’option suivante me semble la plus simple:

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

Voici comment vous pouvez le faire avec for-in boucle.

var children = element.childNodes;

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

Essayez avec la boucle for. Cela donne une erreur dans forEach car c'est une collection de nœuds nodelist.

Ou ceci devrait convertir la liste de noeuds en tableau

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

Ou vous pouvez utiliser ceci

var array = Array.prototype.slice.call(obj);
3
Mritunjay
const results = Array.from(myNodeList.values()).map(parser_item);

NodeList n'est pas un tablea mais NodeList.values ​​() renvoie un Iterator de tableau, ce qui permet de le convertir en tableau.

2
Xu Qinghan

Voici un moyen ES6 fonctionnel d'itérer sur un NodeList. Cette méthode utilise le Array de forEach comme suit:

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

f est la fonction itérateur qui reçoit un nœud enfant en tant que premier paramètre et l'index en tant que second.

Si vous avez besoin d'itérer plusieurs fois sur NodeLists, vous pouvez créer une petite méthode d'utilitaire fonctionnel parmi celles-ci:

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)

(Vous pouvez faire la même astuce pour map() et d'autres fonctions Array.)

1
F Lekschas

Essayez ceci [inversion de l'ordre]:

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

OU [dans l'ordre]

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

Impossible de résister pour ajouter une autre méthode, en utilisant childElementCount. Il retourne le nombre de nœuds d'élément enfant d'un parent donné. Vous pouvez ainsi le parcourir en boucle.

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

Si vous faites beaucoup de ce genre de choses, alors il pourrait être intéressant de définir la fonction pour vous-même.

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 );
        }
    };
}
0
P Hemans