HTML-Collections => Arrays: Reihenfolge?
Andrea 97
- javascript
0 Raketengenauheimer0 JürgenB0 Rolf B
Hallo SelfHTML Gemeinde!
Ich habe eine Frage zu HTML-Collections von getElementsByClassName()!
Wenn ich diese in ein Array konvertiere, kann ich mich drauf verlassen, dass dann Array[0] immer das erste Element im Markup, Array[1] immer das zweite, usw. ist?
Oder ist da wie bei Objekten die Reihenfolge egal?
Vielen lieben Dank, Eure Andi!
Ich habe eine Frage zu HTML-Collections von getElementsByClassName()!
Aha.
Wenn ich diese in ein Array konvertiere,
Wozu willst Du das tun? MDN beschreibt die HTML-Collections als Array-ähnliche Sammlung.
kann ich mich drauf verlassen, dass dann Array[0] immer das erste Element im Markup, Array[1] immer das zweite, usw. ist?
Nicht wenn Du mit JS schon am DOM herumgefummelt hast…
Aber ich kann ja nicht über HTML-Collections iterieren! :(
z.B. forEach
, etc.
...und ja, die Reihenfolge wurde natürlich noch nicht via Javascript vertauscht!
Aber ich kann ja nicht über HTML-Collections iterieren! :(
Wo siehstn du da ein forEach
?
Wo siehstn du da ein
forEach
?
Willst Du nun über die HTML-Collection iterieren oder über die Hilfe meckern?
Welche Hilfe?
Ich weiß jetzt immer noch nicht, ob die Reihenfolge im Markup übernommen wird, wenn ich über HTML-Collection Arrays iteriere
Welche Hilfe?
Nun, ich habe Dir gezeigt, wo steht, wie Du über die die HTML-Collection iterieren kannst. Wie das geht wolltest Du wissen - hast jedenfalls behauptet, Du könntest es nicht.
Ich weiß jetzt immer noch nicht, ob die Reihenfolge im Markup übernommen wird, wenn ich über HTML-Collection Arrays iteriere
https://dom.spec.whatwg.org/#htmlcollection sagt:
„The elements are sorted in tree order.“
Mindestens dann, wenn Deine Elemente alle direkte Kinder ein und desselben Parent-Elements im DOM-Baum („tree“ heißt „Zweig“) sind, dann trifft das demnach zu.
Jörg, getElementsByClassName liefert eine HTMLCollection, keine NodeList. Die forEach Methode gibt's nur in der NodeList.
Man könnte statt getElementsByClassName("foo") auf querySelectorAll(".foo") ausweichen, DER liefert eine Nodelist und da gibt's dann forEach. Außer im Internet Explorer, der will einen Polyfill.
Rolf
Ok, danke danke danke!
Das heißt also laut https://dom.spec.whatwg.org/#htmlcollection
<parent>
<el_1>
<el_2>
<el_3>
</parent>
ergibt die Reihenfolge: HTMLCollection → <el_1> → <el_2> → <el_3>
während aber z.B.
<parent>
<subparent>
<el_1>
<el_2>
</subparent>
</parent>
<parent>
<el_3>
</parent>
die Reihenfolge HTMLCollection → <el_3> → <el_1> → <el_2>
ergibt?
Hallo Andrea 97,
Das heißt also laut https://dom.spec.whatwg.org/#htmlcollection
[…]
ergibt die Reihenfolge:HTMLCollection → <el_1> → <el_2> → <el_3>
während aber z.B.
[…]
die ReihenfolgeHTMLCollection → <el_3> → <el_1> → <el_2>
ergibt?
Das kann man ja einfach mal ausprobieren und in den Browsern testen.
Bis demnächst
Matthias
Jörg, danke für den Link. Das hab ich übersehen.
Hallo Andrea,
nein. Die Spec definiert tree order so:
In tree order is preorder, depth-first traversal of a tree.
Preorder heißt: Zuerst das Root, dann die Children. Und das rekursiv pro Kind.
Wäre in deinem zweiten Beispiel:
root (body)
parent 1
subparent 1
el_1
el_2
parent 2
el_3
Rolf
@@Andrea 97
Aber ich kann ja nicht über HTML-Collections iterieren! :(
Nicht mit forEach
, aber mit for … of
🖖 Stay hard! Stay hungry! Stay alive! Stay home!
Aber ich kann ja nicht über HTML-Collections iterieren! :(
Nicht mit
forEach
, aber mitfor … of
Nur der Vollständigkeit halber:
Mit forEach geht es auch; z.B. für Browser ohne for..of Unterstützung.
// bezieht sich auf Gunnars codePen
Array.prototype.forEach.call(
nephewsNodeList,
function(nephew) {
nephew.style.border = '2px dotted red';
}
);
@@kai345
// bezieht sich auf Gunnars codePen Array.prototype.forEach.call( nephewsNodeList, function(nephew) { nephew.style.border = '2px dotted red'; } );
Für NodeList braucht man das nicht; du meintest nephewsHTMLCollection
:
Array.prototype.forEach.call(
nephewsHTMLCollection,
function(nephew) {
nephew.style.border = '2px dotted red';
}
);
oder auch
Array.prototype.forEach.call(
nephewsHTMLCollection,
nephew => {
nephew.style.border = '2px dotted red';
}
);
HTMLCollection in Array umwandeln kann man so haben:
Array.from(nephewsHTMLCollection).forEach(nephew => {
nephew.style.textDecoration = 'underline';
});
oder kurz
[...nephewsHTMLCollection].forEach(nephew => {
nephew.style.textDecoration = 'underline';
});
🖖 Stay hard! Stay hungry! Stay alive! Stay home!
Hallo,
Iterieren über eine Collection geht auch mit der for-Schleife.
Bisher haben bei mir die getElemets-Methoden die Elemente immer in der Reihenfolge wie im html geliefert. Ob das so sein muss, weiß ich aber nicht genau. Warum ist denn die Reihenfolge wichtig?
Gruß
Jürgen
Hallo Andrea,
wie schon von Raketenjörg gesagt - ein Array braucht es nicht unbedingt.
ES SEI DENN, du willst in der Schleife das DOM verändern. Dann brauchst Du eventuell das Array, weil die HTMLCollection live ist, die spiegelt Änderungen am DOM sofort wieder.
Aber bevor Du das tust, verwende lieber querySelectorAll. Diese Methode liefert Dir eine statische Nodelist. D.h. sie friert den Zustand des DOM in dem Moment, wo die Abfrage stattfand, ein.
document.getElementsByClassName("foo")
und
document.querySelectorAll(".foo")
liefern beide alle Elemente mit Klasse foo. Ersteres als live HTMLCollection, letzteres als statische NodeList, die auch mehr Methoden anbietet.
Eine Reihenfolgegarantie kann ich Dir aber auch nicht geben. Ich finde in der HTML DOM Spezifikation keine Definition dazu. Demnach ist der Browser frei, das Ergebnis nach Belieben zu verwürfeln. Das muss er natürlich nicht tun. Er kann auch eine prefix-Traversierung des DOM Baums vornehmen, die die Elemente in der Reihenfolge liefert wie sie im Sourcecode stehen (ja, ich weiß, wenn man am DOM rumgefummelt hat entspricht es nicht mehr dem Sourcecode).
Rolf
Eine Reihenfolgegarantie kann ich Dir aber auch nicht geben. Ich finde in der HTML DOM Spezifikation keine Definition dazu.
Du hast vermutlich bei der NodeList gesucht, bei querySelectorAll wird man fündig, wenn man den Links folgt.
The querySelectorAll(selectors) method, when invoked, must return the static result of running scope-match a selectors string selectors against this.
Return the result of match a selector against a tree with s and node’s root using scoping root node.
Start with a list of candidate elements, which are the the root elements and all of their descendant elements, sorted in shadow-including tree order, unless otherwise specified.
In shadow-including tree order is shadow-including preorder, depth-first traversal of a node tree.