Ich würde gerne wissen, was genau der Unterschied zwischen querySelector
und querySelectorAll
gegen getElementsByClassName
und ist getElementById
.
Über diesen Link konnte querySelector
ich feststellen, dass ich mit schreiben kann, document.querySelector(".myclass")
um Elemente mit Klasse myclass
und document.querySelector("#myid")
Elemente mit ID zu erhalten myid
. Aber das kann ich schon getElementsByClassName
und getElementById
. Welches sollte bevorzugt werden?
Außerdem arbeite ich in XPages, wo die ID dynamisch mit Doppelpunkt generiert wird und so aussieht view:_id1:inputText1
. Wenn ich schreibe document.querySelector("#view:_id1:inputText1")
, funktioniert es nicht. Aber das Schreiben document.getElementById("view:_id1:inputText1")
funktioniert. Irgendwelche Ideen warum?
quelle
document.querySelectorAll(".myclass")
? Mit usingdocument.querySelector(".myclass")
wird nur das erste übereinstimmende Element zurückgegeben.Antworten:
Die Syntax und die Browserunterstützung.
querySelector
ist nützlicher, wenn Sie komplexere Selektoren verwenden möchten.zB Alle Listenelemente stammen von einem Element ab, das Mitglied der foo-Klasse ist:
.foo li
Das
:
Zeichen hat innerhalb eines Selektors eine besondere Bedeutung. Du musst ihm entkommen. (Das Selektor Escape - Zeichen hat eine besondere Bedeutung in einem JS - String zu, so dass Sie entkommen müssen , dass auch).quelle
getElementById
undgetElementsByClassName
. Die Auswahl von className kann ohne einige hundert Mal langsamer seingetElementsByClassName
.Sammeln aus Mozilla-Dokumentation:
Die NodeSelector-Schnittstelle Diese Spezifikation fügt Objekten, die die Document-, DocumentFragment- oder Element-Schnittstellen implementieren, zwei neue Methoden hinzu:
querySelector
querySelectorAll
und
quelle
In Bezug auf die Unterschiede gibt es einen wichtigen Punkt in den Ergebnissen zwischen
querySelectorAll
undgetElementsByClassName
: Der Rückgabewert ist unterschiedlich.querySelectorAll
gibt eine statische Sammlung zurück, währendgetElementsByClassName
eine Live-Sammlung zurückgegeben wird. Dies kann zu Verwirrung führen, wenn Sie die Ergebnisse zur späteren Verwendung in einer Variablen speichern:querySelectorAll
enthält die Elemente, die den Selektor zum Zeitpunkt des Aufrufs der Methode erfüllt haben .getElementsByClassName
enthält die Elemente, die den Selektor bei seiner Verwendung erfüllt haben (dies kann sich von dem Zeitpunkt unterscheiden, an dem die Methode aufgerufen wurde).Zum Beispiel merken , wie auch wenn Sie die Variablen nicht neu zugewiesen haben
aux1
undaux2
sie enthalten unterschiedliche Werte nach den Klassen der Aktualisierung:quelle
document.getElementsByName
,document.getElementsByTagNameNS
oderdocument.getElementsByTagName
das gleiche Verhalten zeigen.document.getElementById()
gibt keinen Live-Knoten zurück. Es ist schneller alsdocument.querySelector('#id_here')
wahrscheinlich, daquerySelector
zuerst der CSS-Selektor analysiert werden muss.Für diese Antwort verweise ich auf
querySelector
undquerySelectorAll
als querySelector * und aufgetElementById
,getElementsByClassName
,getElementsByTagName
undgetElementsByName
als getElement *.Hauptunterschiede
querySelector
undgetElementById
beide geben ein einzelnes Element zurück.querySelectorAll
undgetElementsByName
beide geben NodeLists zurück, da es sich um neuere Funktionen handelt, die hinzugefügt wurden, nachdem HTMLCollection aus der Mode gekommen war. Die älterengetElementsByClassName
undgetElementsByTagName
beide geben HTMLCollections zurück. Dies ist wiederum im Wesentlichen irrelevant, ob die Elemente aktiv oder statisch sind.Diese Konzepte sind in der folgenden Tabelle zusammengefasst.
Details, Tipps und Beispiele
HTMLCollections sind nicht so arrayartig wie NodeLists und unterstützen .forEach () nicht. Ich finde den Spread-Operator nützlich, um dies zu umgehen:
[...document.getElementsByClassName("someClass")].forEach()
Jedes Element und das globale Element
document
haben Zugriff auf alle diese Funktionen mit Ausnahme vongetElementById
undgetElementsByName
, die nur auf implementiert sinddocument
.Das Verketten von getElement * -Aufrufen anstelle von querySelector * verbessert die Leistung, insbesondere bei sehr großen DOMs. Selbst bei kleinen DOMs und / oder mit sehr langen Ketten ist es im Allgemeinen schneller. Sofern Sie nicht wissen, dass Sie die Leistung benötigen, sollte die Lesbarkeit von querySelector * bevorzugt werden.
querySelectorAll
Das Umschreiben ist oft schwieriger, da Sie bei jedem Schritt Elemente aus der NodeList oder HTMLCollection auswählen müssen. Der folgende Code funktioniert beispielsweise nicht :document.getElementsByClassName("someClass").getElementsByTagName("div")
document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]
Da alle Elemente Zugriff auf die Aufrufe querySelector * und getElement * haben, können Sie mit beiden Aufrufen Ketten erstellen. Dies kann hilfreich sein, wenn Sie einen Leistungsgewinn erzielen möchten, kann jedoch einen querySelector nicht vermeiden, der nicht in Form der Aufrufe getElement * geschrieben werden kann .
Obwohl es im Allgemeinen leicht zu erkennen ist, ob ein Selektor nur mit getElement * -Aufrufen geschrieben werden kann, gibt es einen Fall, der möglicherweise nicht offensichtlich ist:
document.querySelectorAll(".class1.class2")
kann umgeschrieben werden als
document.getElementsByClassName("class1 class2")
Die Verwendung von getElement * für ein statisches Element, das mit querySelector * abgerufen wird, führt zu einem Element, das in Bezug auf die statische Teilmenge des von querySelector kopierten DOM aktiv ist, jedoch nicht in Bezug auf das vollständige Dokument-DOM ... hier ist das Einfache Die Live / Static-Interpretation von Elementen beginnt auseinanderzufallen. Sie sollten wahrscheinlich Situationen vermeiden, in denen Sie sich darüber Sorgen machen müssen. Wenn Sie dies jedoch tun, denken Sie daran, dass querySelector * die gefundenen Kopierelemente aufruft, bevor Sie Verweise auf sie zurückgeben. GetElement * -Aufrufe rufen jedoch direkte Verweise ab, ohne sie zu kopieren.
Keine der APIs gibt an, welches Element zuerst ausgewählt werden soll, wenn mehrere Übereinstimmungen vorliegen.
Da querySelector * das DOM durchläuft, bis eine Übereinstimmung gefunden wird (siehe Hauptunterschied Nr. 2), bedeutet dies auch, dass Sie sich nicht auf die Position eines Elements verlassen können, nach dem Sie im DOM suchen, um sicherzustellen, dass es schnell gefunden wird - das Der Browser kann das DOM rückwärts, vorwärts, zuerst in der Tiefe, zuerst in der Breite oder auf andere Weise durchlaufen. getElement * findet Elemente unabhängig von ihrer Platzierung in ungefähr der gleichen Zeit.
quelle
Ich bin nur auf diese Seite gekommen, um herauszufinden, welche Methode in Bezug auf die Leistung besser zu verwenden ist - dh welche ist schneller:
und ich fand dies: https://jsperf.com/getelementsbyclassname-vs-queryselectorall/18
Es führt einen Test mit den beiden obigen Beispielen durch und führt einen Test für den äquivalenten Selektor von jQuery durch. Meine Testergebnisse waren wie folgt:
quelle
querySelectorAll
zusätzliche Arbeit hinter den Kulissen (einschließlich des Parsens des Selektorausdrucks, der Berücksichtigung von Pseudoelementen usw.), währendgetElementsByClassName
es sich lediglich um eine rekursive Objektdurchquerung handelt.querySelector
kann eine vollständige CSS (3) -Selektor mit IDs und Klassen und Pseudoklassen zusammen sein wie folgt:mit können
getElementByClassName
Sie einfach eine Klasse definierenmit können
getElementById
Sie einfach eine ID definierenquelle
:first
jetzt ein CSS-Selektor?:first-class
, oder:first-of-type
vielleicht, aber ich dachte,:first
es wäre eine JavaScript / jQuery / Sizzle-Ergänzung.:first
merklich nicht:first-child
.querySelector
undquerySelectorAll
sind relativ neue APIs, währendgetElementById
undgetElementsByClassName
sind schon viel länger bei uns. Das bedeutet, dass Ihre Verwendung hauptsächlich davon abhängt, welche Browser Sie unterstützen müssen.Das
:
hat eine besondere Bedeutung, sodass Sie es umgehen müssen, wenn Sie es als Teil eines ID- / Klassennamens verwenden müssen.quelle
querySelectorAll
in IE8 verfügbar,getElementsByClassName
nicht jedoch.querySelectorAll
... im Grunde alles: caniuse.com/#search=querySelectorAllquerySelector
ist von w3c Selector APIgetElementBy
ist von w3c DOM APIIMO ist der bemerkenswerteste Unterschied, dass der Rückgabetyp
querySelectorAll
eine statische Knotenliste undgetElementsBy
eine Live-Knotenliste ist. Daher endet die Schleife in Demo 2 nie, da sielis
live ist und sich bei jeder Iteration selbst aktualisiert.quelle
Unterschied zwischen "querySelector" und "querySelectorAll"
quelle
Schau dir das an
getElementById ist mit 25% am schnellsten als querySelector.
jquery ist am langsamsten
quelle
Der Hauptunterschied zwischen querySelector und getlementbyID (Claassname, Tagname usw.) besteht darin, dass mehr als ein Element die Bedingung erfüllt. QuerySelector gibt nur eine Ausgabe zurück, während getElementBy * alle Elemente zurückgibt.
Betrachten wir ein Beispiel, um es klarer zu machen.
Der folgende Code erklärt den Unterschied
Kurz gesagt, wenn wir ein einzelnes Element auswählen möchten, wählen Sie "Queryslector" oder wenn Sie mehrere Elemente auswählen möchten, wählen Sie "GetElement"
quelle