JavaScript Anfänger

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;
// 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"]');
const currentPath = window.location.pathname;
const navLinks = document.querySelectorAll(".nav-link");

navLinks.forEach(link => {
    if (link.getAttribute("href") === currentPath) {
        link.classList.add("active");
    }
});
const externalLinks = document.querySelectorAll('a[href^="http"]:not([href*="' + location.hostname + '"])');

externalLinks.forEach(link => {
    link.setAttribute("target", "_blank");
    link.setAttribute("rel", "noopener noreferrer");
});

Zusammenfassung

MethodeRückgabeLive?Empfohlen
querySelectorElement / null-✅ Standard
querySelectorAllNodeList❌ Static✅ Standard
getElementByIdElement / null-✅ Für IDs
getElementsByClassNameHTMLCollection✅ Live⚠️ Selten
getElementsByTagNameHTMLCollection✅ Live⚠️ Selten
closestElement / 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.