querySelector – sucht Elemente mit CSS-Selektoren
querySelector() wählt Elemente anhand eines CSS-Selektors (z.B. h1 oder li:active) und ist es ein zentraler Bestandteil der modernen DOM-Manipulation, flexibel und mächtig durch CSS-Selektoren.
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. Der Selektor kann eine CSS-Klasse, eine ID, ein Element wie main oder h2 sein, sogar ein Attribut-Selektor wie input[type="email"] oder eine Pseudo-Klasse wie li:first-child.
<div id="myid"> … </div> <button>Button!</button> <div class="card"> <h2>Produkt</h2> … </div> <input type="email" id="mail"> <ul> <li>Erstes Element</li> <li>Letztes Element</li> </ul>
const myid = document.querySelector("#myid");
const button = document.querySelector("button");
const cardTitle = document.querySelector(".card h2");
/** Zugriff über Attribut-Selektoren **/
const email = document.querySelector('input[type="email"]');
/** Zugriff über Pseudo-Klassen **/
const firstLi = document.querySelector("li:first-child");
querySelector für document oder element
querySelector() sucht in einem Objekt nach dem Element mit dem Selektor – fast immer im document-Objekt. document steht für die komplette HTML-Seite mit allem, was der Browser geladen hat.
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");
Die zweite Anweisung beschränkt die Suche nach dem Selektor article auf den kleineren Raum des Elements main. Das ist präziser und wird in vielen Fällen auch schneller sein.
Hintergründiges: querySelector() ist keine globale Funktion wie alert(), sondern eine Methode eines Objekts. Eigentlich ist alert() auch keine globale Funktion, sondern eine Methode des window-Objekts). document-Object und window-Object spielen die tragende Rolle in Webseiten. Das window-Object repräsentiert das Browserfenster und das document-Object stellt den HTML-Dokumentenbaum für den Zugriff auf alle Elemente der Webseite dar.
querySelector: Nimm nen CSS-Selektor
// das erste h3-Element document.querySelector('h3') //das erste Element mit der Klasse .ci document.querySelector('.ci') // Element mit id="entry" document.querySelector('#entry') // erstes li-Element mit geradem Index document.querySelector('li:nth-child(even)')
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(".box");
if (!elem) {
console.log("Element nicht gefunden");
} else {
…
}
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");
}
Das kann heute auch eleganter mit ?. behandelt werden:
document.querySelector(".box")?.remove();
querySelector mit optional chaining (?.) verhindert Fehler, wenn document.querySelector(".box") null liefert.
Hingegen würde document.querySelector(".box")?.textContent einen Fehler erzeugen, weil Optional Chaining nicht auf der linken Seite einer Zuweisung stehen darf.
Stattdessen gibt es ein nicht minder elegantes
const box = document.querySelector(".box");
box && (box.textContent = "Holla die Waldfee");
closest() – übergeordneten Container finden
Der Weg zu einem Vorfahren war den CSS-Selektoren bis zum Auftritt von CSS :has 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
querySelector und CSS-Pseudo-Klassen
JavaScript kann Pseudo-Klassen direkt selektieren. Das funktioniert, weil Pseudo-Klassen nur Filter auf ein echte Elemente sind.
:hover :focus :checked :first-child :nth-child(3) :has()
const el = document.querySelector('.cups li:nth-child(2)');
Prüfen, ob ein Element einer Pseudo-Klasse genügt:
if (element.matches(':first-child')) {
console.log('erstes Element');
}
querySelector und Pseudo-Elemente
Pseudo-Elemente sind kein Bestandteil des DOM. querySelector und querySelectorAll können keine Pseudo-Elemente wie ::before und ::after erreichen.
<ul class="cups"> <li>Silentium</li> <li>Gaudi</li> <li>Pokal der Stille</li> </ul>
- Silentium
- Gaudi
- Pokal der Stille
Javascript
const icons = [
'pen-line-green.svg',
'book-line-green.svg',
'cup-green.svg'
];
const style = document.createElement('style');
icons.forEach((icon, i) => {
style.textContent += `
.cups li:nth-child(${i+1})::before {
content: url(${icon}) " ";
}
`;
});
document.head.appendChild(style);
document.querySelector('.cups li::before') funktioniert nicht. Das Script greift nicht direkt auf das ::before-Pseudo-Element zu, sondern erzeugt eine neue CSS-Regel, die dieses Pseudo-Element beschreibt. Pseudo-Elemente wie
- ::before
- ::after
- ::marker
- ::first-line
existieren nicht im DOM.
Es gibt zwar getComputedStyle, aber kein setComputedStyle.
let icon = window.getComputedStyle(
document.querySelector('.cups li'),
'::before'
).getPropertyValue('content');
console.log(icon);
Das erste oder alle Elemente mit den Selektor?
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 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.
<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.
$ 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 = "";