Was ist das DOM? JavaScript und HTML verbinden
Was ist das DOM?
Das DOM (Document Object Model) ist die Brücke zwischen JavaScript und HTML. Es ermöglicht dir, Webseiten dynamisch zu verändern – Elemente hinzufügen, entfernen, Styles ändern und auf Benutzeraktionen reagieren.
Das DOM verstehen
Wenn der Browser eine HTML-Datei lädt, erstellt er daraus eine Baumstruktur – das DOM:
<!DOCTYPE html>
<html>
<head>
<title>Meine Seite</title>
</head>
<body>
<h1>Hallo Welt</h1>
<p>Ein Absatz</p>
</body>
</html>
Wird zu diesem Baum:
document
└── html
├── head
│ └── title
│ └── "Meine Seite"
└── body
├── h1
│ └── "Hallo Welt"
└── p
└── "Ein Absatz"
Jedes HTML-Element wird zu einem Node (Knoten) im DOM. JavaScript kann jeden dieser Knoten lesen und verändern.
Das document-Objekt
document ist dein Einstiegspunkt ins DOM:
// Das gesamte HTML-Dokument
console.log(document);
// Der <html>-Tag
console.log(document.documentElement);
// Der <head>-Tag
console.log(document.head);
// Der <body>-Tag
console.log(document.body);
// Der Titel der Seite
console.log(document.title);
document.title = "Neuer Titel!"; // Ändert den Browser-Tab
Elemente finden
getElementById
Findet ein Element anhand seiner ID:
<h1 id="main-title">Willkommen!</h1>
const title = document.getElementById("main-title");
console.log(title); // Das H1-Element
console.log(title.textContent); // "Willkommen!"
querySelector (Empfohlen!)
Findet das erste Element, das zum CSS-Selektor passt:
// Nach ID
const title = document.querySelector("#main-title");
// Nach Klasse
const button = document.querySelector(".btn-primary");
// Nach Tag
const firstParagraph = document.querySelector("p");
// Komplexe Selektoren
const navLink = document.querySelector("nav a.active");
const input = document.querySelector('input[type="email"]');
const firstItem = document.querySelector("ul > li:first-child");
querySelectorAll
Findet alle Elemente, die zum Selektor passen:
// Alle Paragraphen
const paragraphs = document.querySelectorAll("p");
console.log(paragraphs.length); // Anzahl
// Durch alle iterieren
paragraphs.forEach((p, index) => {
console.log(`Paragraph ${index}: ${p.textContent}`);
});
// Alle Buttons mit Klasse
const buttons = document.querySelectorAll(".btn");
// In Array umwandeln (für Array-Methoden)
const buttonsArray = [...document.querySelectorAll(".btn")];
Element-Eigenschaften lesen
<a href="https://example.com" id="link" class="btn primary" data-id="123">
Klick mich
</a>
const link = document.querySelector("#link");
// Text-Inhalt
console.log(link.textContent); // "Klick mich"
// Attribute
console.log(link.href); // "https://example.com"
console.log(link.id); // "link"
console.log(link.className); // "btn primary"
// Dataset (data-* Attribute)
console.log(link.dataset.id); // "123"
// Klassen
console.log(link.classList); // ["btn", "primary"]
Elemente verändern
Text ändern
const title = document.querySelector("h1");
// Text setzen (sicher!)
title.textContent = "Neuer Titel!";
Attribute ändern
const link = document.querySelector("a");
// Attribut setzen
link.href = "https://newsite.com";
link.setAttribute("target", "_blank");
// Attribut lesen
console.log(link.getAttribute("href"));
// Attribut entfernen
link.removeAttribute("target");
// Attribut prüfen
if (link.hasAttribute("href")) {
console.log("Hat href!");
}
Klassen manipulieren
const element = document.querySelector(".box");
// Klasse hinzufügen
element.classList.add("active");
element.classList.add("highlight", "visible"); // Mehrere
// Klasse entfernen
element.classList.remove("active");
// Klasse togglen (an/aus)
element.classList.toggle("active");
// Prüfen ob Klasse existiert
if (element.classList.contains("active")) {
console.log("Ist aktiv!");
}
// Klasse ersetzen
element.classList.replace("old-class", "new-class");
Styles ändern
const box = document.querySelector(".box");
// Einzelne Styles
box.style.backgroundColor = "blue";
box.style.color = "white";
box.style.padding = "20px";
// Achtung: CSS-Eigenschaften in camelCase!
// background-color → backgroundColor
// font-size → fontSize
// Besser: Klassen verwenden!
box.classList.add("highlighted");
Elemente erstellen
Neues Element erstellen
// Element erstellen
const newDiv = document.createElement("div");
// Inhalt setzen
newDiv.textContent = "Ich bin neu!";
newDiv.className = "card";
newDiv.id = "new-card";
// Attribute setzen
newDiv.setAttribute("data-id", "123");
// Zum DOM hinzufügen
document.body.appendChild(newDiv);
Komplexere Elemente
function createCard(title, description) {
const card = document.createElement("div");
card.className = "card";
const cardTitle = document.createElement("h3");
cardTitle.textContent = title;
const cardDesc = document.createElement("p");
cardDesc.textContent = description;
const cardButton = document.createElement("button");
cardButton.textContent = "Mehr erfahren";
cardButton.className = "btn";
// Zusammenbauen
card.appendChild(cardTitle);
card.appendChild(cardDesc);
card.appendChild(cardButton);
return card;
}
// Verwenden
const container = document.querySelector("#cards");
container.appendChild(createCard("Titel 1", "Beschreibung 1"));
container.appendChild(createCard("Titel 2", "Beschreibung 2"));
Elemente einfügen & entfernen
Einfügen
const container = document.querySelector("#container");
const newElement = document.createElement("div");
// Am Ende einfügen
container.appendChild(newElement);
// Am Anfang einfügen
container.prepend(newElement);
// Vor einem Element
const reference = document.querySelector("#reference");
container.insertBefore(newElement, reference);
// Moderne Methoden
container.append(newElement); // Am Ende
container.prepend(newElement); // Am Anfang
reference.before(newElement); // Vor Element
reference.after(newElement); // Nach Element
Entfernen
const element = document.querySelector("#to-remove");
// Modern
element.remove();
// Klassisch (über Parent)
element.parentNode.removeChild(element);
// Alle Kinder entfernen
while (container.firstChild) {
container.removeChild(container.firstChild);
}
DOM Navigation
Von einem Element zu anderen navigieren:
const item = document.querySelector(".item");
// Eltern
item.parentNode; // Direkter Elternknoten
item.parentElement; // Elternelement
item.closest(".container"); // Nächster Vorfahre mit Selektor
// Kinder
item.children; // Alle Kind-Elemente
item.firstElementChild; // Erstes Kind-Element
item.lastElementChild; // Letztes Kind-Element
// Geschwister
item.nextElementSibling; // Nächstes Element
item.previousElementSibling; // Vorheriges Element
Praktisches Projekt: Todo-Liste UI
<div id="todo-app">
<input type="text" id="todo-input" placeholder="Neue Aufgabe...">
<button id="add-btn">Hinzufügen</button>
<ul id="todo-list"></ul>
</div>
const input = document.querySelector("#todo-input");
const addBtn = document.querySelector("#add-btn");
const list = document.querySelector("#todo-list");
function createTodoItem(text) {
const li = document.createElement("li");
li.className = "todo-item";
const span = document.createElement("span");
span.textContent = text;
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "Löschen";
deleteBtn.className = "delete-btn";
// Delete-Funktion
deleteBtn.addEventListener("click", () => {
li.remove();
});
// Abhaken durch Klick
span.addEventListener("click", () => {
li.classList.toggle("completed");
});
li.appendChild(span);
li.appendChild(deleteBtn);
return li;
}
function addTodo() {
const text = input.value.trim();
if (text === "") {
input.focus();
return;
}
const todoItem = createTodoItem(text);
list.appendChild(todoItem);
input.value = "";
input.focus();
}
// Event Listeners
addBtn.addEventListener("click", addTodo);
input.addEventListener("keypress", (e) => {
if (e.key === "Enter") {
addTodo();
}
});
Performance-Tipps
1. Selektoren cachen
// Schlecht - jedes Mal suchen
for (let i = 0; i < 100; i++) {
document.querySelector("#container").appendChild(createItem());
}
// Gut - einmal suchen
const container = document.querySelector("#container");
for (let i = 0; i < 100; i++) {
container.appendChild(createItem());
}
2. DocumentFragment für viele Elemente
const list = document.querySelector("#list");
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i}`;
fragment.appendChild(li); // Kein Reflow
}
list.appendChild(fragment); // Ein Reflow
3. Klassen statt Inline-Styles
// Schlecht - mehrere Reflows
element.style.width = "100px";
element.style.height = "100px";
// Gut - ein Reflow
element.classList.add("red-box");
Zusammenfassung
| Methode | Beschreibung |
|---|---|
querySelector() | Ein Element finden |
querySelectorAll() | Alle Elemente finden |
createElement() | Element erstellen |
appendChild() | Element hinzufügen |
remove() | Element entfernen |
classList.add/remove/toggle() | Klassen ändern |
textContent | Text lesen/setzen |
setAttribute() | Attribut setzen |
Übung: Baue die Todo-Liste nach und erweitere sie um eine “Alle löschen”-Funktion!