Ich versuche, die ID aller Elemente in einem abzurufen HTMLCollectionOf
. Ich habe folgenden Code geschrieben:
var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
console.log(key.id);
}
Aber ich habe die folgende Ausgabe in der Konsole erhalten:
event1
undefined
Das habe ich nicht erwartet. Warum wird die zweite Konsole ausgegeben undefined
, die erste jedoch event1
?
javascript
dom
Neuron
quelle
quelle
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
Antworten:
Als Antwort auf die ursprüngliche Frage verwenden Sie
for/in
falsch. In Ihrem Codekey
ist der Index. Um den Wert aus dem Pseudo-Array zu erhalten, müssten Sie dies tun,list[key]
und um die ID zu erhalten, müssten Sie dies tunlist[key].id
. Aber Sie sollten dies überhaupt nicht tunfor/in
.Zusammenfassung (hinzugefügt im Dezember 2018)
Verwenden Sie
for/in
diese Option niemals zum Iterieren einer NodeList oder einer HTMLCollection. Die Gründe, dies zu vermeiden, werden unten beschrieben.Alle neueren Versionen moderner Browser (Safari, Firefox, Chrome, Edge) unterstützen die
for/of
Iteration in DOM-Listen wienodeList
oderHTMLCollection
.Hier ist ein Beispiel:
Um ältere Browser (einschließlich Dinge wie IE) einzuschließen, funktioniert dies überall:
Erklärung, warum Sie nicht verwenden sollten
for/in
for/in
ist zum Iterieren der Eigenschaften eines Objekts gedacht. Das heißt, es werden alle iterierbaren Eigenschaften eines Objekts zurückgegeben. Während es für ein Array zu funktionieren scheint (Rückgabe von Array-Elementen oder Pseudo-Array-Elementen), kann es auch andere Eigenschaften des Objekts zurückgeben, die nicht den Erwartungen der Array-ähnlichen Elemente entsprechen. Und raten Sie mal, einHTMLCollection
odernodeList
Objekt kann beide andere Eigenschaften haben, die mit einerfor/in
Iteration zurückgegeben werden. Ich habe dies gerade in Chrome versucht. Wenn Sie es so wiederholen, wie Sie es wiederholt haben, werden die Elemente in der Liste (Indizes 0, 1, 2 usw.) abgerufen, aber auch die Eigenschaftenlength
unditem
. Diefor/in
Iteration funktioniert für eine HTMLCollection einfach nicht.Unter http://jsfiddle.net/jfriend00/FzZ2H/ erfahren Sie, warum Sie eine HTMLCollection nicht iterieren können
for/in
.In Firefox ist Ihr
for/in
würde Iteration die folgenden Elemente zurückgeben (alle iterierbaren Eigenschaften des Objekts):Hoffentlich können Sie jetzt sehen, warum Sie
for (var i = 0; i < list.length; i++)
stattdessen verwenden möchten, damit Sie nur erhalten0
,1
und2
in der Iteration.Im Folgenden finden Sie eine Entwicklung der Entwicklung der Browser im Zeitraum 2015-2018, die Ihnen zusätzliche Möglichkeiten zur Iteration bietet. Keines davon wird jetzt in modernen Browsern benötigt, da Sie die oben beschriebenen Optionen verwenden können.
Update für ES6 im Jahr 2015
Zu ES6 wurde hinzugefügt,
Array.from()
dass eine Array-ähnliche Struktur in ein tatsächliches Array konvertiert wird. So kann man eine Liste direkt wie folgt aufzählen:Arbeitsdemo (in Firefox, Chrome und Edge ab April 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Update für ES6 im Jahr 2016
Sie können jetzt das ES6 for / of-Konstrukt mit a
NodeList
und an verwenden,HTMLCollection
indem Sie dies einfach zu Ihrem Code hinzufügen:Dann können Sie Folgendes tun:
Dies funktioniert in der aktuellen Version von Chrome, Firefox und Edge. Dies funktioniert, weil der Array-Iterator sowohl an die NodeList- als auch an die HTMLCollection-Prototypen angehängt wird, sodass beim Array / Iterieren der Array-Iterator verwendet wird, um sie zu iterieren.
Arbeitsdemo: http://jsfiddle.net/jfriend00/joy06u4e/ .
Zweites Update für ES6 im Dezember 2016
Seit Dezember 2016 ist die
Symbol.iterator
Unterstützung für Chrome v54 und Firefox v50 integriert, sodass der folgende Code von selbst funktioniert. Es ist noch nicht für Edge integriert.Arbeitsdemo (in Chrome und Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Drittes Update für ES6 im Dezember 2017
Ab Dezember 2017 funktioniert diese Funktion in Edge 41.16299.15.0 für ein
nodeList
wie indocument.querySelectorAll()
, aber nicht für einHTMLCollection
wie in,document.getElementsByClassName()
sodass Sie den Iterator manuell zuweisen müssen, um ihn in Edge für ein zu verwendenHTMLCollection
. Es ist ein Rätsel, warum sie einen Sammlungstyp reparieren würden, den anderen jedoch nicht. Sie können das Ergebnis vondocument.querySelectorAll()
mit ES6-for/of
Syntax jetzt jedoch zumindest in aktuellen Versionen von Edge verwenden.Ich habe auch die obige jsFiddle aktualisiert, sodass sie sowohl
HTMLCollection
als auchnodeList
separat getestet und die Ausgabe in der jsFiddle selbst erfasst wird.Viertes Update für ES6 im März 2018
Per Mesqueeeb wurde auch
Symbol.iterator
in Safari Unterstützung integriert, sodass Sie diesefor (let item of list)
entweder fürdocument.getElementsByClassName()
oder verwenden könnendocument.querySelectorAll()
.Fünftes Update für ES6 im April 2018
Offenbar Unterstützung für eine Iteration
HTMLCollection
mitfor/of
wird Edge 18 im Herbst 2018 kommen.Sechstes Update für ES6 im November 2018
Ich kann bestätigen, dass Sie mit Microsoft Edge v18 (das im Windows Update vom Herbst 2018 enthalten ist) jetzt sowohl eine HTMLCollection als auch eine NodeList mit for / of in Edge iterieren können.
Daher enthalten jetzt alle modernen Browser native Unterstützung für die
for/of
Iteration sowohl der HTMLCollection- als auch der NodeList-Objekte.quelle
Sie können
for
/in
onNodeList
s oderHTMLCollection
s nicht verwenden . Sie können jedoch einigeArray.prototype
Methoden verwenden, solange Sie.call()
sie verwenden und dasNodeList
oderHTMLCollection
als übergebenthis
.Betrachten Sie Folgendes als Alternative zur Schleife von jfriend00
for
:Es gibt einen guten Artikel über MDN , der diese Technik behandelt. Beachten Sie jedoch die Warnung zur Browserkompatibilität:
Obwohl dieser Ansatz praktisch ist, kann eine
for
Schleife die am besten mit dem Browser kompatible Lösung sein.Update (30. August 2014): Schließlich können Sie ES6
for
/of
!Es wird bereits in neueren Versionen von Chrome und Firefox unterstützt.
quelle
<select multiple>
. Beispiel:[].map.call(multiSelect.selectedOptions, function(option) { return option.value; })
for ... of
funktioniert.In ES6, könnten Sie etwas tun , wie
[...collection]
, oderArray.from(collection)
,Z.B:-
quelle
[...row.cells].forEach
anstelle von arow.querySelectorAll('td')
Sie können diese beiden Zeilen hinzufügen:
HTMLCollection wird von getElementsByClassName und getElementsByTagName zurückgegeben
NodeList wird von querySelectorAll zurückgegeben
So können Sie eine forEach machen:
quelle
NodeList
bereits hatforEach()
.Ich hatte ein Problem mit forEach in IE 11 und auch Firefox 49
Ich habe eine solche Problemumgehung gefunden
quelle
Alternative zu
Array.from
ist zu verwendenArray.prototype.forEach.call
für jedes:
Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });
Karte:
Array.prototype.map.call(htmlCollection, i => { console.log(i) });
ect ...
quelle
Es gibt keinen Grund, es6-Funktionen zu verwenden, um
for
Schleifen zu vermeiden, wenn Sie mit IE9 oder höher arbeiten.In ES5 gibt es zwei gute Optionen. Erstens können Sie "ausleihen"
Array
,forEach
wie Evans erwähnt .Aber noch besser ...
Verwendung
Object.keys()
, die nicht habenforEach
und Filter auf „eigene Eigenschaften“ automatisch.Das heißt,
Object.keys
ist im Wesentlichen gleichbedeutend mit einemfor... in
mit aHasOwnProperty
, ist aber viel glatter.quelle
Ab März 2016
for...of
funktioniert in Chrome 49.0 fürHTMLCollection
:Siehe hier die Dokumentation .
Dies funktioniert jedoch nur, wenn Sie die folgende Problemumgehung anwenden, bevor Sie Folgendes verwenden
for...of
:Das gleiche ist notwendig für die Verwendung
for...of
mitNodeList
:Ich glaube / hoffe, dass
for...of
es bald ohne die oben genannte Problemumgehung funktionieren wird. Die offene Ausgabe ist hier:Update: Siehe Expenzors Kommentar unten: Dies wurde ab April 2016 behoben. Sie müssen HTMLCollection.prototype [Symbol.iterator] = Array.prototype [Symbol.iterator] nicht hinzufügen. über eine HTMLCollection mit for ... of iterieren
quelle
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
, um über einHTMLCollection
mit zu iterierenfor...of
.Am Rande
quelle
Einfache Problemumgehung, die ich immer benutze
Danach können Sie beliebige Array-Methoden für die Auswahl ausführen
quelle
Wenn Sie ältere ES-Varianten verwenden (z. B. ES5), können Sie Folgendes verwenden
as any
:quelle
Sie möchten es ändern in
quelle
for (key in list)
gibt mehrere Eigenschaften von zurückHTMLCollection
, die nicht als Elemente in der Sammlung gedacht sind.