Browser APIs

Das DOM

Das Document Object Model ist die Brücke zwischen Ihrem HTML und Ihrem JavaScript. Lernen Sie, wie Sie Elemente auswählen, erstellen, aktualisieren und entfernen sowie wie Sie auf Benutzerinteraktionen reagieren.

beginner15 min readUpdated 15. Sept. 2026
js
const list = document.querySelector("#todos");
const input = document.querySelector("#todo-input");

function addTodo(text) {
  const li = document.createElement("li");
  li.textContent = text;
  list.append(li);
}

input.addEventListener("keydown", (event) => {
  if (event.key === "Enter") {
    addTodo(input.value);
    input.value = "";
  }
});
Was es ist
Ein Live-Baum aus Objekten
Erstellt durch
Den Browser, basierend auf Ihrem HTML
Auswahl mit
querySelector / querySelectorAll
Reaktion mit
addEventListener
Erstellung mit
document.createElement
Kosten
Layout- und Paint-Operationen

Praxis

DOM-Manipulation ausprobieren

Klicken Sie auf den Button und bearbeiten Sie dann den Code, um zu sehen, wie sich der Baum verändert.

DOM-Manipulation ausprobieren

Klicken Sie auf den Button und bearbeiten Sie dann den Code, um zu sehen, wie sich der Baum verändert.

Warum es wichtig ist

Warum das DOM wichtig ist

Ihr HTML als Objekte

Der Browser parst das Markup in einen Baum aus Nodes, den Ihr Code jederzeit lesen und ändern kann.

Sofortiges Feedback

Aktualisieren Sie den Baum und der Browser zeichnet die Seite automatisch neu – kein Page-Reload, kein Server-Roundtrip.

Auf alles reagieren

Klicks, Tastatureingaben, Scrolling, Resizing, Netzwerk-Events und mehr gelangen über ein einziges Event-Modell zu Ihnen.

Das Gesamtbild

Die drei Kernkonzepte des DOM

Jede DOM-Aufgabe ist eine Kombination aus denselben drei Schritten: etwas finden, es ändern oder darauf reagieren.

Der Baum

Struktur

Eine Hierarchie von Nodes, in der jedes Element, Attribut und Textstück einen festen Platz und einen Parent hat.

Selektion

Finden & Ändern

Fragen Sie den Baum ab und lesen oder schreiben Sie dann Texte, Attribute, Klassen und Styles in den gefundenen Nodes.

Events

Reagieren

Hören Sie auf Benutzer- und Browser-Events und führen Sie daraufhin Code aus – idealerweise mittels Delegation.

DOM auf einen Blick

Was Sie mit dem DOM machen können

Elemente auswählen

querySelector gibt den ersten Treffer zurück, querySelectorAll gibt alle Treffer als statische Liste zurück.

Lesen & Schreiben

textContent, innerHTML, Attribute und dataset ermöglichen es Ihnen, Inhalte zu prüfen und zu aktualisieren.

Klassen & Styles

classList und die style-Property ändern das Aussehen, ohne ein Stylesheet direkt zu bearbeiten.

Nodes erstellen

createElement, append, prepend und remove lassen den Baum je nach Bedarf wachsen oder schrumpfen.

Events

addEventListener abonniert Klicks, Input, Tastatur, Scroll und vieles mehr.

Event-Delegation

Ein einziger Listener an einem Parent kann Events von all seinen Children verarbeiten, selbst wenn diese erst später hinzugefügt wurden.

Eine kurze Geschichte

Die Entwicklung des DOM

  1. 1996

    Das erste DOM

    Netscape und Microsoft führen konkurrierende Wege zum Scripting von Seiten ein, was den ersten Browserkrieg auslöst.

    96
  2. 1998

    DOM Level 1

    Das W3C standardisiert ein gemeinsames Baummodell und eine geteilte API zur Manipulation desselben.

    98
  3. 2009

    querySelector erscheint

    Selektoren im CSS-Stil machen das Finden von Elementen dramatisch einfacher und ausdrucksstärker.

    09
  4. 2015

    classList und moderne APIs

    classList, dataset und template vereinfachen die tägliche DOM-Arbeit und ersetzen alte Workarounds.

    15
  5. Heute

    Ein Living Standard

    Das DOM wird als kontinuierlich aktualisierte Spezifikation mit breitem Konsens unter den Browsern gepflegt.

    Heute

Der vollständige Leitfaden

Das DOM: Alles was Sie wissen müssen

Was ist das DOM?

Wenn der Browser dein HTML liest, speichert er dies nicht als einfachen Textstring. Er erstellt einen Baum aus Objekten, das sogenannte Document Object Model. Jedes Element wird zu einem Node mit Eigenschaften und Methoden, jedes Attribut ist zugänglich und jedes Textstück hat seinen festen Platz. Das DOM ist dieser Baum, und er ist live: Ändere ihn, und die Seite aktualisiert sich.

Das ist der Grund, warum JavaScript und HTML so eng miteinander verknüpft sind. Dein HTML beschreibt die Struktur, der Browser wandelt diese in Objekte um und JavaScript manipuliert diese Objekte. Das document-Objekt ist dabei der Einstiegspunkt in den gesamten Baum.

Der Node-Baum

Das DOM ist hierarchisch aufgebaut. document ist die Wurzel (Root), <html> ist dessen Kind und alles Weitere hängt in einer Eltern-Kind-Beziehung darunter. Ein Node kann viele Kinder haben, aber nur einen einzigen Eltern-Node.

document
└── html
    ├── head
    │   └── title
    └── body
        ├── h1
        └── p

Es gibt verschiedene Arten von Nodes. Element-Nodes repräsentieren Tags. Text-Nodes enthalten die Zeichen innerhalb von Elementen. Comment-Nodes repräsentieren Kommentare. Meistens arbeitet man mit Elementen, aber das Wissen um die Existenz von Text-Nodes erklärt unerwartete Leerzeichen und warum childNodes mehr enthalten kann, als man eigentlich erwartet.

Elemente auswählen

Bevor Sie etwas ändern können, müssen Sie es zuerst finden. Das moderne Standardwerkzeug ist querySelector, welches jeden CSS-Selektor akzeptiert.

// select.js
const title = document.querySelector("h1");
const firstCard = document.querySelector(".card");
const allLinks = document.querySelectorAll("a[target='_blank']");
const byId = document.getElementById("main");

allLinks.forEach((link) => link.classList.add("external"));

querySelector gibt das erste passende Element oder null zurück. querySelectorAll gibt eine statische NodeList aller Treffer zurück, die forEach unterstützt, sich jedoch nicht aktualisiert, wenn sich der DOM ändert. Die älteren Methoden getElementById, getElementsByClassName und getElementsByTagName funktionieren weiterhin; die letzten beiden geben live Collections zurück, die sich automatisch aktualisieren.

Inhalte lesen und schreiben

Sobald Sie ein Element haben, können Sie dessen Inhalt lesen oder ersetzen.

// content.js
const heading = document.querySelector("#title");

heading.textContent;          // read the visible text
heading.textContent = "Hello"; // replace it, escaped as text

heading.innerHTML = "<em>Hi</em>"; // parses HTML

Verwenden Sie textContent immer dann, wenn der Wert von einem Benutzer, einer API oder aus einer anderen Quelle stammt, die Sie nicht vollständig kontrollieren. Dabei wird alles als einfacher Text behandelt, sodass kein Markup injiziert werden kann. innerHTML parst einen String als HTML, was für vertrauenswürdige Templates praktisch ist, aber bei nicht vertrauenswürdigen Eingaben ein ernsthaftes Cross-Site Scripting-Risiko darstellt. Wenn Sie Markup aus Daten generieren müssen, ist es besser, Elemente zu erstellen und für jedes einzelne textContent zu setzen.

Attribute, Klassen und Styles

Attribute befinden sich direkt am Element und können unmittelbar ausgelesen oder geändert werden.

// attrs.js
const link = document.querySelector("a");

link.getAttribute("href");
link.setAttribute("href", "/docs");
link.dataset.userId = "42"; // data-user-id="42"

link.classList.add("active");
link.classList.toggle("open");
link.classList.remove("hidden");

link.style.color = "tomato";

classList ist der saubere Weg, um Klassen zu verwalten – so vermeidet man String-Konkatenation und versehentliche doppelte Klassen. Die style-Property setzt Inline-Styles für jede Eigenschaft einzeln; für thematische Anpassungen ist es besser, eine Klasse zu toggeln und die Entscheidung CSS zu überlassen.

Knoten erstellen, einfügen und entfernen

Sie erstellen neue Knoten mit document.createElement und platzieren diese mithilfe der Einfügemethoden.

// build.js
const item = document.createElement("li");
item.textContent = "New task";
item.classList.add("task");

const list = document.querySelector("#todos");
list.append(item);       // add at the end
list.prepend(item);      // add at the start
item.remove();           // detach from the tree

append akzeptiert mehrere Knoten und sogar Strings, während insertBefore eine präzise Platzierung ermöglicht. Wenn Sie viele Knoten einfügen müssen, erstellen Sie diese außerhalb des Dokuments und hängen Sie sie einmalig an:

// fragment.js
const fragment = document.createDocumentFragment();
for (const name of names) {
  const li = document.createElement("li");
  li.textContent = name;
  fragment.append(li);
}
list.append(fragment);

Ein DocumentFragment ist ein leichtgewichtiger Container, der nicht Teil der Seite ist. Durch das Anhängen werden alle seine Kinder in einem einzigen Vorgang verschoben, was deutlich weniger Layout-Arbeit auslöst, als wenn sie einzeln hinzugefügt würden.

Auf Events hören

Events sind die Art und Weise, wie dein Code auf den Nutzer und den Browser reagiert. Füge einen Listener mit addEventListener hinzu.

// events.js
const button = document.querySelector("#save");

button.addEventListener("click", (event) => {
  event.preventDefault();
  console.log("clicked", event.target);
});

Das Event-Objekt enthält nützliche Informationen: target ist das Element, das das Event ausgelöst hat, currentTarget ist das Element, an das der Listener gebunden ist, und preventDefault() verhindert das Standardverhalten des Browsers. Zu den gängigen Events gehören click, input, change, submit, keydown, scroll und DOMContentLoaded.

Event-Delegation

Anstatt jedem Kindelement einen Listener zuzuweisen, hängen Sie einen an ein Elternelement an und untersuchen Sie event.target. Da Events vom Zielelement aus über seine Vorfahren nach oben bubbeln, sieht das Elternelement sie alle.

// delegate.js
const list = document.querySelector("#todos");

list.addEventListener("click", (event) => {
  const button = event.target.closest("button.delete");
  if (!button) return;
  button.closest("li").remove();
});

Dies ist effizienter und sorgt vor allem dafür, dass die Funktionalität auch für Elemente erhalten bleibt, die erst nach dem Hinzufügen des Listeners erstellt wurden. Für dynamische Listen und Tabellen ist Delegation das Standard-Pattern.

Durchlaufen des Baums

Manchmal muss man sich von einem Knoten zu seinen verwandten Knoten bewegen.

// traverse.js
const item = document.querySelector(".item");

item.parentElement;        // nearest ancestor element
item.children;             // child elements only
item.firstElementChild;    // first child element
item.nextElementSibling;   // next sibling element
item.closest(".card");     // nearest ancestor matching a selector

Die Element-Varianten überspringen Text- und Kommentar-Knoten, was fast immer das gewünschte Ergebnis ist. closest ist besonders nützlich in Event-Handlern, wie das Beispiel zur Delegation zeigt.

Performance und Best Practices

  • Bündeln Sie Lese- und Schreibvorgänge. Das Auslesen von Layout-Eigenschaften wie offsetHeight zwingt den Browser zur Neuberechnung; das Abwechseln von Lese- und Schreibvorgängen führt zu wiederholten Reflows.
  • Off-document aufbauen. Verwenden Sie ein DocumentFragment oder ein Element außerhalb des sichtbaren Bereichs und fügen Sie es erst am Ende einmalig ein.
  • Lookups cachen. Speichern Sie Elemente in Variablen, anstatt sie innerhalb einer Schleife erneut abzufragen.
  • Klassen gegenüber Inline-Styles bevorzugen. Schalten Sie eine Klasse um und halten Sie die Darstellung im CSS.
  • Standardmäßig textContent verwenden. Nutzen Sie innerHTML nur bei vertrauenswürdigen, bereinigten Inhalten.
  • Event-Delegation nutzen für Listen und alle dynamischen Elemente.
  • Listener entfernen, die nicht mehr benötigt werden – insbesondere auf langlebigen Seiten –, um Memory Leaks zu vermeiden.

Häufige Fehler

  • Ein Element abfragen, bevor es existiert, und sich dann wundern, warum es null ist.
  • innerHTML mit Benutzereingaben verwenden und damit eine XSS-Lücke öffnen.
  • Einen Listener an jede einzelne Zeile hängen, anstatt das Event an die Tabelle zu delegieren.
  • Layout-Properties innerhalb derselben Schleife lesen und schreiben.
  • event.target und event.currentTarget verwechseln.
  • Davon ausgehen, dass querySelectorAll live ist, obwohl es sich um einen statischen Snapshot handelt.

Wie geht es weiter?

Das DOM ist der Knotenpunkt für alles, was Sie bisher gelernt haben. Kombinieren Sie es mit der ES6+ Syntax für saubereren Code, versorgen Sie es mit Daten über die Fetch API und machen Sie es durch Error Handling robust. Der schnellste Weg, dies zu verinnerlichen, ist es, etwas Kleines – eine To-do-Liste, eine filterbare Galerie oder eine Live-Suche – komplett in vanilla JavaScript nachzubauen.

Text sicher setzen

textContent behandelt die Eingabe als reinen Text. innerHTML parst sie als Markup, was bei nicht vertrauenswürdigen Daten ein XSS-Risiko darstellt.

Bevorzugt
const comment = "<b>hi</b>";
el.textContent = comment;
// renders the literal text
Vermeiden
const comment = "<img src=x onerror=alert(1)>";
el.innerHTML = comment;
// executes markup

Auf Klicks hören

Delegieren Sie an einen Parent, damit später hinzugefügte Elemente ebenfalls funktionieren und Sie nur einen statt vieler Listener benötigen.

Bevorzugt
list.addEventListener("click", (e) => {
  const li = e.target.closest("li");
  if (li) li.remove();
});
Vermeiden
document.querySelectorAll("li")
  .forEach((li) => {
    li.addEventListener("click", () => li.remove());
  });

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, DOM Manipulation zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch DOM Manipulation — mit Quizzen und echtem Code, den Sie im Browser ausführen können.