2013-02-26 8 views
15

Ich habe eine <div> mit einem Kind <div> drin. Z.B.Warum funktioniert forEach nicht für Kinder?

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

ich versuchte, durch sie in einer Schleife mit der forEach Funktion, weil ich dachte, dass document.getElementById("niceParent").children ist ein Array, wie ich die Elemente zugreifen kann mit

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

Daher habe ich versucht

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

was nicht funktioniert. Ich bekomme

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

Als Abhilfe, die ich versuchte es auch mit-viel mehr complicated- for..in Schleife:

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

, die wie erwartet gearbeitet.

Warum?

Antwort

31

Da .children eine NodeList[MDN] enthält, kein Array. Ein NodeList Objekt ist ein Array-artiges Objekt, das eine .length Eigenschaft macht und numerische Eigenschaften hat, nur wie Arrays, aber es funktioniert nicht erbt von Array.prototype und somit ist kein Array.

Sie können es auf ein Array konvertieren Array.prototype.slice Verwendung:

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

ECMAScript 6 führen eine neue API für Iteratoren und arrayartige Objekte reale Arrays Umwandeln: Array.from[MDN]. Verwenden Sie das, wenn es möglich ist, da es die Absicht viel klarer macht.

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

Ich möchte sowohl Felix Kling als auch lonesomeday antworten, da sie t sind er selbe trotz einiger Aliase benutzt. Vielen Dank. Speziell für den Link zu MDN. – erik

+0

In ECMAScript6 kann man 'Array.prototype.from()' verwenden, um die Absicht einer übersichtlicheren Umwandlung in ein Array anzugeben. –

+0

@ АндрейБеньковский: guter Punkt! Ich werde meine Antwort aktualisieren. –

6

Element.children ist nicht ein Array. Es ist ein DOM-Objekt namens NodeList. Diese haben keine Array-Funktionen (obwohl sie die length Eigenschaft haben).

durchgeschleift es, Sie werden es in ein Array umwandeln müssen, die Sie Array.prototype.slice verwenden können:

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

Sie können dies auch tun:

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

Und danach Sie können forJe nach Ihrer Sammlung anrufen:

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

Das wird jedoch Schwierigkeiten verursachen, wenn es mit dem Ansatz "for..in" kombiniert wird. – lonesomeday

+1

Ich empfehle den Artikel zu lesen: ["Was ist falsch mit der Erweiterung des DOM"] (http://perfectionkills.com/whats-wrong-with-extending-the-dom/). –

+0

Trotzdem ist es interessant zu wissen, dass dies möglich ist. – erik