Javascript-Sammlung von DOM-Objekte - warum kann ich nicht rückwärts mit Array.reverse()?
-
09-06-2019 - |
Frage
Was könnte das problem mit der Umkehr der array von DOM-Objekten, wie im folgenden code:
var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();
In Firefox 3, wenn ich rufen Sie die reverse()
Methode Stoppt das Skript ausgeführt wird, und zeigt die folgende Fehlermeldung in der Konsole die Web-Developer-Toolbar:
imagesArr.reverse is not a function
Die imagesArr
Variablen Durchlaufen werden können, die durch mit einer for-Schleife und Elemente wie imagesArr[i]
zugegriffen werden kann, also warum ist es nicht als ein array beim Aufruf der reverse()
Methode?
Lösung
Weil getElementsByTag Namen tatsächlich gibt eine NodeList-Struktur.Es hat ähnliche array wie Indexierung Eigenschaften für syntaktische Bequemlichkeit, aber es ist nicht ein array ist.Für Beispiel, die Menge der Einträge ist eigentlich ständig dynamisch aktualisiert, wenn Sie hinzufügen ein neues img-tag unter myDivHolderId, erscheint es automatisch in imagesArr.
Finden http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 für mehr.
Andere Tipps
getElementsByTag()
gibt eine NodeList anstelle eines Arrays.Sie können konvertieren eine NodeList in ein Array, aber beachten Sie, dass das array ein anderes Objekt, so umkehren, es wird nicht Einfluss auf die DOM-Knoten position.
var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img");
var arrayNodes = Array.slice.call(listNodes, 0);
arrayNodes.reverse();
Um die position zu ändern, werden Sie haben zu entfernen Sie die DOM-Knoten und fügen Sie Sie alle wieder in die richtige position.
Array.prototype.slice.call(arrayLike, 0)
ist ein guter Weg, um zu konvertieren ein array wie ein array, aber wenn Sie mit einer JavaScript-Bibliothek, kann es tatsächlich einen noch besseren/schnelleren Weg, es zu tun.Für Beispiel, jQuery $.makeArray(arrayLike)
.
Sie können auch mithilfe der Array-Methoden direkt auf der NodeList:
Array.prototype.reverse.call(listNodes);
getElementsByTag()
gibt eine NodeList anstelle eines Arrays.Sie müssen konvertieren die NodeList in ein array, dann reverse es.
var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();
Ich weiß, diese Frage ist alt, aber ich denke, es braucht ein wenig Aufklärung, da einige der Antworten hier sind veraltet W3C verändert die definition, und somit der Rückgabewert dieser Methoden getElementsByTagName()
und getElementsByClassName()
Diese Methoden zum Zeitpunkt des Schreibens dieser Antwort gibt ein Objekt zurück - leer oder nicht - der Typ HTMLCollection
und nicht NodeList
.
Es ist wie der Unterschied zwischen den Eigenschaften children
das gibt ein Objekt vom Typ HTMLCollection
da es nur aus Elementen und ohne text-oder kommentarknoten, und childNodes
das gibt ein Objekt vom Typ NodeList
da könnte es mit anderen node-Typen wie text und Kommentare.
Hinweis:Ich gehe auf die Tangente hier und drücke meinen Mangel an Einsicht, warum querySelectorAll()
Methode momentan gibt ein NodeList
und nicht eine HTMLCollection
da arbeitet ausschließlich auf element-Knoten im Dokument, und sonst nichts.
Wahrscheinlich hat es etwas zu tun mit Potenzial Berichterstattung über andere Arten von Knoten in die Zukunft, und Sie gingen für eine zukunftssichere Lösung, wer weiß das wirklich?:)
EDIT:Ich glaube, ich habe die Logik hinter dieser Entscheidung für eine NodeList
und nicht eine HTMLCollection
für die querySelectorAll()
.
Da Sie konstruiert HTMLCollection
werden ausschließlich und vollständig live und da diese Methode nicht brauchen, diese live-Funktionalität, entschieden Sie sich für ein NodeList
Implementierung statt, um das beste für seinen Zweck wirtschaftlich und effizient.
Ihre erste Linie irrelevant, da es nicht zwingen, die Zuweisung auf die variable, in javascript funktioniert anders.imagesArr, ist nicht vom Typ Array(), seine von dem, was der Rückgabetyp getElementsByTagName("img") ist.In diesem Fall ist eine HtmlCollection in Firefox 3.
Die einzigen Methoden auf diesem Objekt sind die Indexer, und die Länge.Um rückwärts arbeiten, nur rückwärts Durchlaufen.