querySelector – Zugriff über CSS-Selector

Javascript querySelector

querySelector () wählt Elemente anhand eines CSS-Selektors (z.B. h1, div.note, #foo oder li:active) aus und gibt das erste Element mit dem passenden CSS-Selektor zurück. querySelector und querySelectorAll sind das Pendant zu jQuery $ im naturreinen Javascript (liebevoll als Vanilla Javascript bezeichnet).

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Vom CSS-Selektor zu querySelector

querySelector (elem) wird mit einem CSS-Selektor aufgerufen und gibt das erste Element zurück, auf das der Selektor passt. Wenn mehr als ein passendes Element gefunden wird, gibt querySelector das erste gefundene Element zurück, querySelectorAll eine Liste aller gefundenen Elemente. Das Argument von querySelector ist ein String mit der Syntax für den CSS-Selektor – wie in der CSS-Datei oder im style-Tag.

<h1 class="header"> … </h1>
…
const header = document.querySelector ("h1.header");

Wenn alle Elemente gefordert sind, die einem CSS-Selektor entsprechen, sammelt querySelectorAll alle Elemente mit diesem Selektor in einer HTMLCollection, einem Array-ähnlichen Datentyp.

sandwich donut sable
<div class="flex">
	<img loading="lazy" src="sandwich.webp" …>
	<img loading="lazy" src="donut.webp" …>
	<img loading="lazy" src="sable.webp" …>
</div>
			
const images = document.querySelectorAll (".flex img");

querySelector() und querySelectorAll() lösen komplexe CSS-Query-Strings auf, die von getElementById, getElementsByTagName oder getElementsByClassName nur mit großem Aufwand umsetzen können.

querySelector für document oder element

querySelector () kann sowohl für einen Elementknoten wie div oder form als auch für document aufgerufen werden.

const main = document.querySelector("main");
const article = main.querySelector("article");

$ statt document.querySelector

Wer von jQuery zurück zu den Wurzeln und nativem Javascript will, ist leicht brüskiert vom Schreibaufwand für document.querySelector(".foo") anstelle des schlichten $(".foo"). Da gibt es Abhilfe: Einfach das $-Zeichen an document.querySelector binden und $$ an document.querySelectorAll.

const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);

const pics = $$("img");
$$('img').forEach(img => console.log(img.src))

const headsvg = $("#headsvg");

$(".excerpt").innerHTML = "";

querySelector: Nimm nen CSS-Selektor

document.querySelector('h3')          das erste h3-Element     

document.querySelector('.ci')         das erste Element mit der Klasse .ci

document.querySelector('#entry')      Element mit id="entry"

document.querySelector('li:nth-child(even)') erstes li-Element mit geradem Index          

querySelector und querySelectorAll sind flexibler als document.getElementById und getElementsByTagName oder getElementsByClassName und obendrein schneller.

Beide Methoden können sowohl den ganzen DOM-Baum als auch einen einzelnen Zweig parsen. Jeder CSS-Selektor funktioniert als Parameter.

let bluetext = document.querySelector('h3[style="color:blue"]').innerText;

querySelector-Check – Element existiert?

Wenn kein Element mit dem Selektor existiert, gibt querySelector(".selector") null zurück.

const elem = document.querySelector('.selector') !== null;
if (elem) {
	console.log ("Hier gibts was zu holen");
} else {
	console.log ("Nichts in Sicht");
}

oder

const elem = document.querySelector('.selector');
if (elem !== null) {
	console.log ("Hier gibts den Verweis auf auf ein " + elem.tagName + " mit CSS-Klasse selector");
} else {
	console.log ("Auf dieser Seite ist kein Element mit CSS-Klasse selector");
}

Der große Bruder von querySelector ist querySelectorAll, das alle Elemente mittels Selektoren als NodeList zurück gibt. Wenn kein entsprechendes Element existiert, gibt querySelectorAll(".selector") eine leere Liste zurück.

if (document.querySelectorAll(".foo").length === 0) {
   console.log ("keine Elemente gefunden");
}

closest() – übergeordneten Container finden

Viele der praktischen Methoden aus jQuery haben ihren Web ins Vanilla Javascript gefunden und erweitern die Queries / Abfragen nach bestimmten Elementen.

Der Weg zu einem Vorfahren ist den CSS-Selektoren (noch) verwehrt – sie greifen nicht von unten nach oben. querySelector sucht – wie CSS – von einem Element aus ebenfalls nach unten. JS closest () ist eine Art Umkehrung und selektiert Parent-Elemente oder Vorfahren nach oben und kann mit querySelector kombiniert werden, das wiederum nach unten sucht.

elem.closest(".item").querySelector(".note")  sucht .note unter dem nahegelegensten Vorfahren mit .item
Javascript closest – parent selector
CSS kennt (noch) keinen Selektor, der von div.note auf das list-Element führt.

closest () wird von IE11 (RIP) nicht unterstützt. Ein Polyfil für closest gibt es bei GitHub.

querySelector und Pseudo-Elemente

Pseudo-Elemente sind kein Bestandteil des DOM. Vor querySelector und querySelectorAll konnte Javascript keine Pseudo-Elemente wie ::before und ::after erreichen. In der Tat schafft das nicht einmal jQuery.

Mit getComputedStyle funktioniert dann der Zugriff auf Pseudo-Elemente:

  • Silentium
  • Gaudi
  • Pokal der Stille
CSS / HTML
.cups li:nth-child(1)::before { 
   content: "url(icon-pen.png) ";
}

<ul class="cups">
   <li>Silentium</li>
   …
Javascript
let icon = window.getComputedStyle (
   document.querySelector('.cups li'), ':before').getPropertyValue('content');
console.log (icon);

Da wir hier ein Pseudo-Element vor uns haben und Pseudo-Elemente kein Teil des DOMs sind, kann Javascript die CSS-Regel auch nicht ohne Weiteres ändern.

Es gibt zwar getComputedStyle, aber kein setComputedStyle. Javascript kann allerdings ein style-Element anlegen und das Pseudo-Element mit innerHTML beschreiben.

let style = document.createElement('style');
style.innerHTML = '.cups li:nth-child(1)::before {content: url(icon-pen-green.png) " "}';

document.querySelector('head').appendChild(style);

querySelector hängt das style-Element anschließend mit appendChild an das Ende von head.