DOM-Elemente selektieren
DOM-Elemente selektieren
Bevor du HTML-Elemente ändern kannst, musst du sie finden. JavaScript bietet mehrere Methoden dafür - und jede hat ihren Anwendungsfall.
Die wichtigsten Selektoren
querySelector - Der Allrounder
querySelector findet das erste Element, das zum CSS-Selektor passt:
// Nach ID
const header = document.querySelector("#header");
// Nach Klasse
const button = document.querySelector(".btn-primary");
// Nach Tag
const firstParagraph = document.querySelector("p");
// Kombinierte Selektoren
const navLink = document.querySelector("nav a.active");
const emailInput = document.querySelector('input[type="email"]');
const firstListItem = document.querySelector("ul > li:first-child");
querySelectorAll - Alle Treffer
querySelectorAll findet alle Elemente, die zum Selektor passen:
// Alle Paragraphen
const paragraphs = document.querySelectorAll("p");
console.log(paragraphs.length); // Anzahl
// Alle Buttons mit Klasse
const buttons = document.querySelectorAll(".btn");
// Alle Links in der Navigation
const navLinks = document.querySelectorAll("nav a");
Wichtig: querySelectorAll gibt eine NodeList zurück, kein Array!
const items = document.querySelectorAll(".item");
// forEach funktioniert
items.forEach(item => console.log(item));
// Aber nicht alle Array-Methoden!
// items.map(...) // ❌ Fehler!
// In Array umwandeln
const itemsArray = [...items];
// oder
const itemsArray2 = Array.from(items);
// Jetzt funktioniert alles
itemsArray.map(item => item.textContent);
getElementById - Schnell & direkt
getElementById ist die schnellste Methode für IDs:
const element = document.getElementById("main-content");
// Ohne #
// document.getElementById("#main"); // ❌ Falsch!
// document.getElementById("main"); // ✅ Richtig!
getElementsByClassName
const cards = document.getElementsByClassName("card");
// Gibt HTMLCollection zurück (live!)
console.log(cards.length);
console.log(cards[0]);
// Kein forEach! In Array umwandeln:
[...cards].forEach(card => console.log(card));
getElementsByTagName
const divs = document.getElementsByTagName("div");
const inputs = document.getElementsByTagName("input");
CSS-Selektoren für querySelector
Du kannst alle CSS-Selektoren verwenden:
Einfache Selektoren
// Tag
document.querySelector("div");
document.querySelector("p");
// ID (#)
document.querySelector("#header");
document.querySelector("#main-content");
// Klasse (.)
document.querySelector(".card");
document.querySelector(".btn-primary");
// Attribut
document.querySelector('[type="submit"]');
document.querySelector('[data-id="123"]');
document.querySelector('[href^="https"]'); // Beginnt mit
document.querySelector('[src$=".png"]'); // Endet mit
document.querySelector('[class*="btn"]'); // Enthält
Kombinierte Selektoren
// Element mit Klasse
document.querySelector("button.primary");
document.querySelector("input.form-control");
// Mehrere Klassen
document.querySelector(".card.featured");
document.querySelector(".btn.btn-large.active");
// ID und Klasse
document.querySelector("#nav.sticky");
Hierarchie-Selektoren
// Nachfahre (irgendwo drin)
document.querySelector("nav a");
document.querySelector(".container .card");
// Direktes Kind (>)
document.querySelector("ul > li");
document.querySelector(".menu > .item");
// Direkter Nachbar (+)
document.querySelector("h1 + p"); // p direkt nach h1
// Alle folgenden Geschwister (~)
document.querySelector("h1 ~ p"); // Alle p nach h1
Pseudo-Selektoren
// Position
document.querySelector("li:first-child");
document.querySelector("li:last-child");
document.querySelector("li:nth-child(2)");
document.querySelector("li:nth-child(odd)");
document.querySelector("li:nth-child(even)");
// Nicht-Selektor
document.querySelector("input:not([type='submit'])");
document.querySelector(".item:not(.disabled)");
// Formular-Status
document.querySelector("input:checked");
document.querySelector("input:disabled");
document.querySelector("input:required");
Von einem Element aus suchen
Du kannst auch von einem Element aus suchen:
const nav = document.querySelector("nav");
// Suche nur innerhalb von nav
const activeLink = nav.querySelector(".active");
const allLinks = nav.querySelectorAll("a");
closest - Nach oben suchen
closest findet den nächsten Vorfahren (inkl. sich selbst):
const button = document.querySelector(".delete-btn");
// Finde das umgebende Card-Element
const card = button.closest(".card");
// Finde das umgebende Formular
const form = button.closest("form");
// Kein Treffer = null
const table = button.closest("table"); // null wenn nicht in Tabelle
Praktisches Beispiel: Event Delegation
document.querySelector(".card-list").addEventListener("click", (e) => {
// Wurde ein Delete-Button geklickt?
const deleteBtn = e.target.closest(".delete-btn");
if (deleteBtn) {
// Finde die zugehörige Card
const card = deleteBtn.closest(".card");
card.remove();
}
});
DOM Navigation
Von einem Element zu verwandten Elementen:
Eltern
const element = document.querySelector(".child");
// Direkter Elternknoten
element.parentNode;
// Direktes Elternelement
element.parentElement;
// Nächster Vorfahre mit Selektor
element.closest(".container");
Kinder
const container = document.querySelector(".container");
// Alle Kindknoten (inkl. Text, Kommentare)
container.childNodes;
// Nur Element-Kinder
container.children;
// Erstes/Letztes Kind
container.firstElementChild;
container.lastElementChild;
// Anzahl Kinder
container.children.length;
container.childElementCount;
Geschwister
const item = document.querySelector(".item");
// Nächstes Element
item.nextElementSibling;
// Vorheriges Element
item.previousElementSibling;
// Alle Geschwister sammeln
function getAllSiblings(element) {
return [...element.parentElement.children].filter(
child => child !== element
);
}
Spezielle Selektoren
Formulare
// Alle Formulare
document.forms;
document.forms[0];
document.forms["login-form"];
// Form-Elemente
const form = document.querySelector("form");
form.elements;
form.elements["email"];
form.elements.password;
Bilder, Links, Anker
// Alle Bilder
document.images;
// Alle Links
document.links;
// Alle Anker
document.anchors;
document.body & document.head
// Immer verfügbar
document.body;
document.head;
document.documentElement; // <html>
Live vs. Static Collections
HTMLCollection (live): Aktualisiert sich automatisch
const divs = document.getElementsByTagName("div");
console.log(divs.length); // z.B. 5
document.body.appendChild(document.createElement("div"));
console.log(divs.length); // 6 - automatisch aktualisiert!
NodeList von querySelectorAll (static): Snapshot
const divs = document.querySelectorAll("div");
console.log(divs.length); // 5
document.body.appendChild(document.createElement("div"));
console.log(divs.length); // immer noch 5!
Performance-Tipps
1. Selektoren cachen
// ❌ Schlecht - jedes Mal suchen
for (let i = 0; i < 100; i++) {
document.querySelector("#container").appendChild(/* ... */);
}
// ✅ Gut - einmal suchen
const container = document.querySelector("#container");
for (let i = 0; i < 100; i++) {
container.appendChild(/* ... */);
}
2. ID ist am schnellsten
// 🚀 Am schnellsten
document.getElementById("header");
// ⚡ Schnell
document.querySelector("#header");
// 🐌 Langsamer (komplexer Selektor)
document.querySelector("body > header.main-header");
3. Scope einschränken
// Suche im gesamten Dokument
document.querySelectorAll(".item");
// Besser: Suche nur wo nötig
const list = document.querySelector("#my-list");
list.querySelectorAll(".item");
4. Spezifisch sein
// ❌ Zu allgemein
document.querySelectorAll("div");
// ✅ Spezifisch
document.querySelectorAll(".card");
document.querySelectorAll('[data-component="card"]');
Null-Checks
querySelector gibt null zurück wenn nichts gefunden:
const element = document.querySelector(".maybe-exists");
// ❌ Kann crashen
element.classList.add("active"); // TypeError wenn null!
// ✅ Mit Check
if (element) {
element.classList.add("active");
}
// ✅ Mit Optional Chaining
element?.classList.add("active");
// ✅ Mit Nullish Coalescing
const text = element?.textContent ?? "Default";
Praktische Beispiele
Formular-Validierung vorbereiten
const form = document.querySelector("#signup-form");
const emailInput = form.querySelector('[name="email"]');
const passwordInput = form.querySelector('[name="password"]');
const submitBtn = form.querySelector('[type="submit"]');
Navigation Highlighting
const currentPath = window.location.pathname;
const navLinks = document.querySelectorAll(".nav-link");
navLinks.forEach(link => {
if (link.getAttribute("href") === currentPath) {
link.classList.add("active");
}
});
Alle externen Links finden
const externalLinks = document.querySelectorAll('a[href^="http"]:not([href*="' + location.hostname + '"])');
externalLinks.forEach(link => {
link.setAttribute("target", "_blank");
link.setAttribute("rel", "noopener noreferrer");
});
Zusammenfassung
| Methode | Rückgabe | Live? | Empfohlen |
|---|---|---|---|
querySelector | Element / null | - | ✅ Standard |
querySelectorAll | NodeList | ❌ Static | ✅ Standard |
getElementById | Element / null | - | ✅ Für IDs |
getElementsByClassName | HTMLCollection | ✅ Live | ⚠️ Selten |
getElementsByTagName | HTMLCollection | ✅ Live | ⚠️ Selten |
closest | Element / null | - | ✅ Nach oben |
// Merksatz:
// querySelector(All) → Moderner Standard
// getElementById → Schnellste für IDs
// closest → Vorfahren finden
Übung: Schreibe eine Funktion $(selector, context), die wie jQuery funktioniert: $(".card") findet alle Cards, $(".item", container) findet Items nur in container.