Es nervt mich, dass ich nicht document.querySelectorAll(...).map(...)
einmal in Firefox 3.6 etwas tun kann und immer noch keine Antwort finde. Deshalb dachte ich, ich würde die Frage aus diesem Blog auf SO posten:
http://blowery.org/2008/08/29/yay-for-queryselectorall-boo-for-staticnodelist/
Kennt jemand einen technischen Grund, warum Sie kein Array erhalten? Oder warum ein StaticNodeList nicht aus einem Array in einer solchen Art und Weise erben , dass Sie nutzen könnten map
, concat
etc?
(Übrigens, wenn es nur eine Funktion ist, die Sie möchten, können Sie so etwas wie NodeList.prototype.map = Array.prototype.map;
... aber warum ist diese Funktionalität (absichtlich?) Überhaupt blockiert?)
Antworten:
Ich glaube, es ist eine philosophische Entscheidung des W3C. Das Design des W3C DOM [spec] ist ziemlich senkrecht zur Gestaltung von JavaScript, wie die DOM ist gemeint Plattform und sprachneutral sein.
Entscheidungen wie "
getElementsByFoo()
gibt eine Bestellung zurückNodeList
" oder "querySelectorAll()
gibt eine zurückStaticNodeList
" sind sehr beabsichtigt, sodass Implementierungen sich nicht darum kümmern müssen, ihre zurückgegebene Datenstruktur basierend auf sprachabhängigen Implementierungen auszurichten (wie.map
sie in Arrays in JavaScript und Ruby verfügbar sind) nicht auf Listen in C #).Das W3C Ziel niedrig: sie werden sagen , ein
NodeList
eine enthalten sollten nur lesbar.length
Eigenschaft vom Typ unsigned long , weil sie glauben , dass jede Implementierung zumindest Unterstützung , dass , aber sie werden nicht sagen ausdrücklich , dass der[]
soll Indexoperator immer Positionselemente zur Unterstützung überlastet werden, weil sie keine arme kleine Sprache unterdrücken wollen, die implementiert werden will,getElementsByFoo()
aber das Überladen von Operatoren nicht unterstützen kann. Es ist eine weit verbreitete Philosophie, die in weiten Teilen der Spezifikation vorhanden ist.John Resig hat eine ähnliche Option wie Ihre geäußert , zu der er hinzufügt :
Ich kann mich ein wenig einfühlen. Wenn das DOM speziell für JavaScript-Funktionen geschrieben wurde, wäre es viel weniger umständlich und intuitiver zu bedienen. Gleichzeitig verstehe ich die Designentscheidungen des W3C.
quelle
StaticNodeList
in ein Array konvertieren würden . Ich würde die Antwort von @ mck89 als den Weg zur Konvertierung einesNodeList
/StaticNodeList
in ein natives Array unterstützen, aber das wird im IE (8 obv) mit einem JScript-Fehler fehlschlagen, da diese Objekte gehostet werden / "special".document
,window
IE, usw. oft implementiert dieser „speziell“ (zum Beispiel als COM - Objekte) , die manchmal nicht Übereinstimmen normaler Verwendung in kleiner und subtilen Art und Weise, wie dieArray.prototype.slice.call
Bombardierung als gegeben einStaticNodeList
;)Sie können den Spread-Operator ES2015 (ES6) verwenden :
[...document.querySelectorAll('div')]
konvertiert StaticNodeList in Array von Elementen.
Hier ist ein Beispiel für die Verwendung.
quelle
Array.from(document.querySelectorAll('div')).map(x => console.log(x.innerHTML))
Ich weiß nicht, warum es eine Knotenliste anstelle eines Arrays zurückgibt, vielleicht weil es wie getElementsByTagName das Ergebnis aktualisiert, wenn Sie das DOM aktualisieren. Eine sehr einfache Methode, um dieses Ergebnis in ein einfaches Array umzuwandeln, ist:
und dann können Sie tun:
quelle
slice
Linie.Nur um zu dem hinzuzufügen, was Crescent gesagt hat:
Tu das nicht! Es ist überhaupt nicht garantiert zu funktionieren.
Kein JavaScript- oder DOM / BOM-Standard gibt an, dass die
NodeList
Konstruktorfunktion sogar als globale /window
Eigenschaft existiert oder dass dieNodeList
zurückgegebene Funktion vonquerySelectorAll
ihr erbt oder dass ihr Prototyp beschreibbar ist oder dass die FunktionArray.prototype.map
tatsächlich auf einer NodeList funktioniert.Eine NodeList darf ein 'Host-Objekt' sein (und ist eines im IE und einigen älteren Browsern). Die
Array
Methoden sind so definiert, dass sie mit jedem nativen JavaScript-Objekt ausgeführt werden dürfen, das Zahlen undlength
Eigenschaften verfügbar macht. Sie müssen jedoch nicht mit Hostobjekten arbeiten (und im IE nicht).Es ist ärgerlich, dass Sie nicht alle Array-Methoden in DOM-Listen erhalten (alle, nicht nur StaticNodeList), aber es gibt keinen zuverlässigen Weg, dies zu umgehen. Sie müssen jede DOM-Liste, die Sie erhalten, manuell in ein Array konvertieren:
quelle
new Array(n)
gibt dem JS-Terp nur einen Hinweis darauf, wie lange das Array enden wird. Dies könnte es ihm ermöglichen, diese Menge an Speicherplatz im Voraus zuzuweisen, was möglicherweise zu einer Beschleunigung führen würde, da einige Speicherumverteilungen vermieden werden könnten, wenn das Array wächst. Ich weiß nicht, ob es in modernen Browsern tatsächlich hilft ... Ich würde nicht messbar vermuten.Ich denke, Sie können einfach folgen
Es funktioniert perfekt für mich
quelle
Dies ist eine Option, die ich zu den anderen Möglichkeiten hinzufügen möchte, die andere hier vorschlagen. Es ist nur für intellektuellen Spaß gedacht und wird nicht empfohlen .
Nur zum Spaß , hier ist eine Möglichkeit, "zu zwingen", sich
querySelectorAll
zu knien und sich vor dir zu verbeugen:Jetzt fühlt es sich gut an, diese Funktion zu durchlaufen und zu zeigen, wer der Boss ist. Jetzt weiß ich nicht, was besser ist, wenn ich einen ganz neuen Wrapper für benannte Funktionen erstelle und dann Ihren gesamten Code diesen seltsamen Namen verwenden lasse (so ziemlich im jQuery-Stil) oder die Funktion wie oben einmal überschreibe, damit der Rest Ihres Codes noch in der Lage ist um den ursprünglichen DOM-Methodennamen zu verwenden
querySelectorAll
.quelle