W3docs

JavaScript-Suche: getElement*, querySelector*

Das DOM meistern: getElementById, querySelector und querySelectorAll für interaktive JavaScript-Webanwendungen erklärt.

Bevor Sie etwas auf einer Seite ändern, verschieben oder lesen können, müssen Sie das gewünschte Element finden. Dies ist der allererste Schritt bei nahezu jeder DOM-Aufgabe, und JavaScript bietet Ihnen dafür zwei Methodenfamilien:

  • Klassische getElement*-MethodengetElementById, getElementsByClassName, getElementsByTagName. Sie sind schnell und geben live Collections zurück.
  • Moderne querySelector*-MethodenquerySelector, querySelectorAll. Sie akzeptieren beliebige CSS-Selektoren und geben statische Ergebnisse zurück.

Dieser Leitfaden behandelt beide Familien, die Hilfsmethoden matches, closest und contains zum Prüfen und Durchlaufen des Baums sowie den wichtigsten Fallstrick: den Unterschied zwischen einer live Collection und einer statischen. Jedes Beispiel ist ausführbar, sodass Sie das Ergebnis sofort sehen können.

Sobald Sie ein Element gefunden haben, bestehen die nächsten Schritte gewöhnlich darin, den DOM zu traversieren, um benachbarte Elemente zu erreichen, und den DOM zu manipulieren, um ihn zu verändern. Einen sanfteren Überblick finden Sie unter DOM-Elemente auswählen.

Effizienter Elementzugriff: getElementById

Die Methode getElementById ist der schnellste und zuverlässigste Weg, auf ein einzelnes Element zuzugreifen, da eine ID innerhalb eines Dokuments eindeutig sein soll und Browser IDs intern indizieren. Sie gibt das übereinstimmende Element zurück oder null, wenn kein Element mit dieser ID existiert — prüfen Sie daher auf null, bevor Sie das Ergebnis verwenden. Beachten Sie, dass Sie die reine ID übergeben, ohne führendes # (das gilt nur für CSS-Selektoren). Im folgenden Beispiel wird der anfängliche „Standardtext" sofort ersetzt.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<head>
    <title>getElementById Example</title>
</head>
<body>
    <div id="main-content">Default text</div>
    <script>
        const element = document.getElementById('main-content');
        element.innerHTML = "Modified text!"
    </script>
</body>
</html>

Mehrere Elemente ansprechen: getElementsByClassName und getElementsByTagName

Info

Wenn Sie Elemente nach Klassenname oder Tag-Name auswählen, erhalten Sie eine HTMLCollection zurück. Dies ist eine live Collection: Sie aktualisiert sich automatisch, wenn sich der DOM ändert. Sie ist array-ähnlich — Sie können Elemente per Index lesen (els[0]) und els.length prüfen — aber sie ist kein echtes array, weshalb forEach, map oder filter fehlen. Um sie sicher zu iterieren, konvertieren Sie sie zunächst mit Array.from(...) (oder dem Spread-Operator [...els]).

Beispiel mit getElementsByClassName

Greifen Sie mit getElementsByClassName auf mehrere Elemente mit derselben Klasse zu. In diesem Beispiel haben wir zwei div-Elemente mit demselben Klassennamen. Wir ändern beide, indem wir sie anhand ihres Klassennamens auswählen.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<head>
    <title>getElementsByClassName Example</title>
</head>
<body>
    <div class="info">First Info</div>
    <div class="info">Second Info</div>
    <script>
        const infoElements = document.getElementsByClassName('info');
        Array.from(infoElements).forEach(el => el.innerHTML = "MODIFIED!");
    </script>
</body>
</html>

Beispiel mit getElementsByTagName

Rufen Sie Elemente anhand ihres Tag-Namens mit getElementsByTagName ab. Dies funktioniert ganz ähnlich wie das vorherige Beispiel, aber diesmal wählen wir nach dem Tag-Namen aus, nicht nach dem Klassennamen.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<head>
    <title>getElementsByTagName Example</title>
</head>
<body>
    <p>First Paragraph</p>
    <p>Second Paragraph</p>
    <script>
        const paragraphs = document.getElementsByTagName('p');
        Array.from(paragraphs).forEach(el => el.innerHTML = "MODIFIED!");
    </script>
</body>
</html>

Flexible Suchen mit querySelector und querySelectorAll

Auswählen mit querySelector

Verwenden Sie querySelector, um das erste Element zu finden, das einem CSS-Selektor entspricht. In diesem Beispiel wählen wir das erste Element mit der Klasse text aus, das ein direktes Kind des Elements mit der ID main ist.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<head>
    <title>QuerySelector Example</title>
</head>
<body>
    <div id="main"><span class="text">This will be replaced</span></div>
    <div id="other"><span class="text">This one doesn't change</span></div>
    <script>
        const spanInsideDiv = document.querySelector('#main > .text');
        spanInsideDiv.innerHTML = "MODIFIED!";
    </script>
</body>
</html>

Mehrere Elemente abrufen mit querySelectorAll

querySelectorAll gibt alle Elemente zurück, die einem CSS-Selektor entsprechen, als statische NodeList. Praktischerweise besitzt eine NodeList ein eingebautes forEach, sodass Sie sie direkt iterieren können, ohne sie vorher in ein array umzuwandeln.

Das Wort statisch ist wichtig: querySelectorAll erstellt eine Momentaufnahme der Treffer zum Zeitpunkt des Aufrufs. Wenn Sie danach übereinstimmende Elemente hinzufügen oder entfernen, ändert sich diese Momentaufnahme nicht. Dies ist genau das Gegenteil der live HTMLCollection, die die getElementsBy*-Methoden zurückgeben.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<head>
    <title>QuerySelectorAll Example</title>
</head>
<body>
    <ul>
        <li class="item">Item 1</li>
        <li class="item">Item 2</li>
    </ul>
    <script>
        const items = document.querySelectorAll('.item');
        items.forEach(item => item.innerHTML = "MODIFIED!");
    </script>
</body>
</html>

Live vs. Statisch: Die Collection-Falle

Dies ist die Falle, in die die meisten Einsteiger tappen. Eine live HTMLCollection spiegelt bei jedem Zugriff den aktuellen Zustand des DOM wider, während eine statische NodeList zum Zeitpunkt der Auswahl eingefroren wird. Der folgende Codeausschnitt zeigt beide Varianten im Umgang mit einem neu hinzugefügten Element:

// Suppose the page has two <li class="item"> elements.
const live = document.getElementsByClassName('item');   // live HTMLCollection
const snapshot = document.querySelectorAll('.item');     // static NodeList

console.log(live.length);     // 2
console.log(snapshot.length); // 2

// Now add a third matching element.
const li = document.createElement('li');
li.className = 'item';
document.querySelector('ul').appendChild(li);

console.log(live.length);     // 3  — updated automatically
console.log(snapshot.length); // 2  — still the old snapshot

Warum das wichtig ist: Das Iterieren über eine live Collection, während übereinstimmende Elemente entfernt werden, ist eine klassische Quelle für übersprungene Elemente, weil die Collection unter Ihnen schrumpft. Eine statische NodeList aus querySelectorAll ist für diesen Fall sicherer, da sich die Liste während der Schleife nicht verändert.

Prüfen und Traversieren: matches, closest und contains

Bei der Suche geht es nicht nur darum, Elemente zu finden — oft haben Sie ein Element und müssen eine Frage dazu stellen.

  • element.matches(selector) gibt true zurück, wenn das Element selbst dem CSS-Selektor entspricht. Ideal für Event-Delegation.
  • element.closest(selector) geht vom Element aus aufwärts im Baum (sich selbst eingeschlossen) und gibt den nächsten Vorfahren zurück, der übereinstimmt, oder null.
  • parent.contains(node) gibt true zurück, wenn node der Elternteil selbst oder ein Nachfahre davon ist.

<!-- snippet: html-result -->

<!DOCTYPE html>
<html>
<body>
    <section class="card">
        <button id="save" class="btn primary">Save</button>
    </section>
    <div id="out"></div>
    <script>
        const btn = document.getElementById('save');
        const section = document.querySelector('.card');
        const out = document.getElementById('out');

        out.innerHTML =
            'matches(".primary"): ' + btn.matches('.primary') + '<br>' +
            'closest(".card") is section: ' + (btn.closest('.card') === section) + '<br>' +
            'section.contains(btn): ' + section.contains(btn);
    </script>
</body>
</html>

Welche Methode sollte ich verwenden?

  • Benötigen Sie ein Element anhand seiner ID? Verwenden Sie getElementById — es ist am schnellsten und klarsten.
  • Benötigen Sie einen CSS-Selektor (Nachfahren, Kombinatoren, Attribute, :not())? Verwenden Sie querySelector / querySelectorAll.
  • Benötigen Sie eine live Liste, die DOM-Änderungen nachverfolgt? Verwenden Sie getElementsByClassName / getElementsByTagName.
  • Haben Sie ein Element und müssen den Baum prüfen oder aufsteigen? Verwenden Sie matches, closest oder contains.

Fazit

Das Finden von Elementen ist die Grundlage jedes DOM-Skripts. Greifen Sie für einzelne IDs auf getElementById zurück, nutzen Sie querySelector* für die Flexibilität von CSS-Selektoren, und verwenden Sie die getElementsBy*-Methoden, wenn Sie tatsächlich eine live Collection benötigen — denken Sie dabei stets an den Unterschied zwischen live und statisch, damit Collections Sie nicht mitten in einer Schleife überraschen. Von hier aus fahren Sie fort mit DOM traversieren und DOM-Manipulation.

Übungen

Übung
Welche der folgenden Aussagen über JavaScripts querySelector- und getElementById-Methoden sind korrekt?
Welche der folgenden Aussagen über JavaScripts querySelector- und getElementById-Methoden sind korrekt?
Was this page helpful?