2013-02-26 13 views
15

Ho un <div> con un bambino <div> in esso. Per esempio.Perché per Each non funziona per i bambini?

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

Ho provato a ciclo attraverso di loro con la funzione forEach, perché ho pensato che document.getElementById("niceParent").children è un array, posso accedere agli elementi con

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

Quindi ho cercato

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

che non funziona. Ottengo

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

Per aggirare il problema ho anche provato con un-molto più complicated- for..in ciclo:

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

che ha funzionato come previsto.

Perché?

risposta

31

Perché .children contiene un NodeList[MDN], non un array. Un oggetto NodeList è un oggettomatrice simile, che espone una proprietà .length ed ha proprietà numeriche, proprio come matrici, ma non eredita da Array.prototype e quindi non è un array.

È possibile convertirlo in un array usando Array.prototype.slice:

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

ECMAScript 6 introduce una nuova API per la conversione di iteratori e oggetti array simile agli array reali: Array.from[MDN]. Usalo se possibile poiché rende l'intento molto più chiaro.

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

Vorrei accettare sia la risposta di Felix Kling che quella di risposta solitaria, poiché sono t lui stesso nonostante alcuni alias usati. Grazie. Soprattutto per il collegamento a MDN. – erik

+0

In ECMAScript6 si può usare 'Array.prototype.from()' per indicare l'intento di convertire in una matrice in un modo più chiaro. –

+0

@ АндрейБеньковский: buon punto! Aggiornerò la mia risposta –

6

Element.children è non un array. È un oggetto DOM chiamato NodeList. Questi non hanno le funzioni di un array (sebbene abbiano la proprietà length).

Per eseguire un ciclo attraverso di essa, si dovrà convertirlo in un array, che si può fare utilizzando Array.prototype.slice:

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

È anche possibile fare questo:

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

E dopo questo puoi chiamare perOut nella tua raccolta:

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

Ciò tuttavia causerà difficoltà se combinato con l'approccio 'for..in'. – lonesomeday

+1

Consiglio di leggere l'articolo: ["Cosa c'è di sbagliato nell'estensione del DOM"] (http://perfectionkills.com/whats-wrong-with-extending-the-dom/). –

+0

Tuttavia è interessante sapere che questo è possibile. – erik

Problemi correlati