JavaScript: Umfassender Zugriff auf DOM-Elemente mit „querySelector()“

Die bisherigen Möglichkeiten, auf DOM-Elemente zuzugreifen, beschränkte sich auf drei Methoden. Möglich war der Zugriff auf ein Element mit einer bestimmten ID, auf Elemente einer bestimmten Klasse und auf Elemente eines bestimmten Typs. Sobald mehrere unterschiedliche Elemente und Klassen berücksichtigt werden sollten, wurde es kompliziert.
JavaScript-Zugriff ohne Selector-API
Möchte man beispielsweise auf alle P-Elemente derselben Klasse zugreifen und gleichzeitig auf alle SPAN-Elemente, um diese fett auszuzeichnen, musste man das bislang relativ umständlich angehen:
for (var i = 0; i < document.getElementsByTagName("p").length; i++) { if (document.getElementsByTagName("p")[i].className == "info") { document.getElementsByTagName("p")[i].style.fontWeight = "bold"; } } for (var i = 0; i < document.getElementsByTagName("span").length; i++) { document.getElementsByTagName("span")[i].style.fontWeight = "bold"; }
Da gerade solche Zugriffe nicht selten sind, bringen viele JavaScript-Frameworks wie jQuery Funktionen mit, mit denen sich solche Zugriffe vereinfacht ausführen lassen. Mittlerweile gibt es jedoch native JavaScript-Methoden, die denselben Dienst leisten wie die entsprechenden Funktionen der Frameworks.
Native Selector-API von JavaScript
Die zwei Methoden „querySelector()“ und „querySelectorAll()“ vereinfachen den komplexen Zugriff auf DOM-Elemente. Mit „querySelector()“ kann man auf das erste zutreffende Element zugreifen, während „querySelectorAll()“ alle zutreffenden Elemente in einem Array zurückgibt, so wie es beispielsweise auch „getElementsByTagName()“ macht.
Das oben vorgestellte Beispiel lässt sich dank „querySelectorAll()“ kürzer ausdrücken:
for (var i = 0; i < document.querySelectorAll("p.info, span").length; i++) { document.querySelectorAll("p.info, span")[i].style.fontWeight = "bold"; }
Um mit der Selector-API Elemente anzusprechen, bedient sie sich derselben Syntax, wie sie bei CSS-Angaben verwendet wird. Sie kann auf diese Weise auch als Ersatz für „getElementById()“ verwendet werden:
document.querySelector("#kopf").style.color = "red";
Auch die Methoden „getElementsByTagName()“ und „getElementsByClassName()“ kann sie ersetzen und bietet dabei noch einen sehr viel differenzierteren Einsatz. Lassen sich mit den beiden alten Methoden jeweils nur ein Elementtyp beziehungsweise eine Klasse abfragen, kann man mit „querySelector()“ und „querySelectorAll()“ mehrere Elemente und Klassen kombinieren:
document.querySelector("h1, h2, h3").style.color = "red"; document.querySelector("p, .info").style.fontWeight = "bold";
Die erste Angabe berücksichtigt alle H1-, H2- und H3-Elemente und die zweite Angabe alle P-Elemente sowie alle Elemente mit der Klasse „info“. Geändert wird in diesen Fällen nur das jeweils erste Element, das die Kriterien erfüllt. Mit „querySelectorAll()“ und einer „for“-Schleife lassen sich alle Elemente ändern, die die Kriterien erfüllen.
Auch Tiefen- und Geschwisterselektoren, wie man sie von CSS kennt, können angewendet werden. So kann man beispielsweise auf P-Elemente zugreifen, die einem H1-Element folgen:
document.querySelector("h1 + p").style.fontWeight = "bold";
Fazit
Die beiden neuen Methoden bieten endlich eine flexible Möglichkeit, auf DOM-Elemente zuzugreifen, ohne die bisherigen Methoden aufwändig miteinander kombinieren zu müssen. Alle aktuellen Browser, auch der Internet Explorer, unerstützen die Selector-API. Wer bislang jQuery eingesetzt hat, um schnell und einfach auf DOM-Elemente zuzugreifen, kann fortan die Selector-API verwenden.
Setzt ihr „querySelector()“ und „querySelectorAll()“ bereits ein? Wie sind eure Erfahrungen damit?
Weiterführende Links zum Thema JavaScript:
- JavaScript: Mit File-API auf lokale Dateien zugreifen
- Impress.js: Cooles Präsentationtool mit HTML5 und CSS3
- HTML5 und Local Storage: Daten für Offlinebetrieb speichern
Sofern man jQuery nur aufgrund der Selector-API nutzt, wäre dies möglicherweise eine Alternative… aber wer macht das schon? Ist zwar interessant solche Techniken mal erleutert zu bekommen, aber man muss doch wirklich nicht das Rad neu erfinden.
@Martin: Nicht nur möglicherweise, sondern sogar eine sehr gute Alternative! Diese nativen Methoden vom Browser sind schneller als die Methoden von Frameworks. Und „erläutert“ wird so geschrieben ;)
Heili Geili, das hätte ich gestern gerade gebrauchen können :-)
Aber es ging dann auch mit getElementsByID.
Aber es wird das neue wohl nur funktionieren, wenn auch der Doctype HTML 5 ist, oder nicht?
@Mansur
Mit dieser Aussage wäre ich vorsichtig. jQuery beispielsweise nutzt die API sobald verfügbar und greift dann nicht mehr auf Sizzle zurück. Zum Nachesen: http://blog.bigbinary.com/2010/02/15/how-jquery-selects-elements-using-sizzle.html. Und ich würde vermuten, dass Dojo, YUI und andere ähnlich verfahren. Es gibt also keinen zwangsläufigen Performancenachteil bei der Verwendung eines JS Frameworks.
Hier kann man einen Test zwischen jQuery und querySelector aufrufen:
http://jsperf.com/test-document-queryselector
jQuery muss sich da meiner Meinung nach nicht verstecken. Grundsätzlich
sollte man u.a. bei der Auswahl des Selectors darauf achten, dass dieser
so geschrieben ist, um optimal zu performen. Oder beim Aufruf einer
Schleife ist es oftmals auch besser, die native JS Methode aufzurufen und
eben nicht .each(). Man muss halt immer den Einzelfall betrachten…
Das tut doch weh. Man möge bitte Ergebnisse cachen und nicht in jedem Durchgang die komplette Liste 2x erstellen lassen!
wie kann ich diese beiden befehle:
document.querySelector(„.view-sonne h2 .view-sonne p „).style.opacity=1;
zusammen fassen