2016-07-03 25 views
1

Also lassen Sie uns sagen, dass ich ein Array von DOM-Elemente haben:Javascript html dom Array-Elemente in Schleife

var z = document.getElementsByClassName('name'); 

und für jedes Element möchte ich mit Attribut für in-Schleife:

for(var n in z){z[n].setAttribute('marked', '1');} 

Für obigen Code bekomme ich z[n].setAttibute is not a function. Wenn ich jedoch Konsolenelemente des z-Arrays manuell einchecke, wurde das Attribut marked jedem Element hinzugefügt. Warum passiert das und wie kann ich einen solchen Fehler verhindern?

+0

n ist das Element, kein Index, tun n.setAttribute. Sie sollten einen traditionellen Zähler für eine Nodeliste verwenden. – Li357

+2

Eine Nodelist ist Array-ähnlich, eine reguläre For-Schleife ist wahrscheinlich geeigneter. – adeneo

+0

Siehe [Warum ist die Verwendung von "for ... in" mit Array-Iteration eine schlechte Idee?] (Http://stackoverflow.com/q/500504/1529630) – Oriol

Antwort

2

document.getElementsByClassName gibt eine Instanz von HTMLCollection zurück, ein array-ähnliches Objekt. for..in Schleife wurde für Objekte, nicht für Arrays entwickelt. Es durchläuft alle Eigenschaften eines Objekts. Daher erhalten Sie bei der Iteration durch HTMLCollection neben Array-Indizes auch andere Eigenschaften wie length. Als length ist einfach eine Zahl, es hat keine setAttribute Methode, so dass Sie diesen Fehler bekommen.

Sie entweder eine regelmäßige for Schleife verwenden sollten, oder for..of Schleife:

const z = document.getElementsByClassName('name') 

// Regular loop: 
for (let i = 0, len = z.length; i < len; i++) { 
    z[i].setAttribute('marked', '1') 
} 

// for..of loop: 
for (const element of z) { 
    element.setAttribute('marked', '1') 
} 

Sie können auch HTMLCollection zu Array konvertieren Array.from() verwenden. Dann können Sie alle Array-Methoden auf sie verwenden, zum Beispiel .forEach():

const z = Array.from(document.getElementsByClassName('name')) 

z.forEach(element=> element.setAttribute('marked', '1')) 
+1

'getElementsByClassName' gibt eine' HTMLCollection' zurück, keine 'NodeList'. Der Unterschied ist relevant, weil DOM4 NodeList [iterable] (http://heycam.github.io/webidl/#idl-iterable) erstellt hat, so dass Sie 'forEach' direkt verwenden können. – Oriol

+0

@Oriol Danke, korrigiert. –

0
[].forEach.call(z, function(el) { 
el.setAttribute('marked', '1'); 
}) 

for..in erhält alle Schlüssel der HTMLCollection, einschließlich der Eigenschaft .length. .length ist eine Zahl und hat keine .setAttribute-Funktion.