mitmario.dev

Was das DOM ist

JavaScript Im Browser 3 Min Lesezeit 4 BeispieleLektion 1 von 7

Ab hier hat JavaScript etwas, mit dem es arbeiten kann: die Seite. Bevor du sie ansprichst, lohnt sich eine Minute für die Frage, was du da eigentlich ansprichst.

Aus Markup werden Objekte

Aus Markup werden Objekte
// Aus <p class="hinweis">Willkommen</p> ist ein Objekt geworden.
const absatz = document.querySelector("p");

console.log("Ein Objekt:", typeof absatz);
console.log("Tag:", absatz.tagName);
console.log("Text:", absatz.textContent);
console.log("Klasse:", absatz.className);

// Und es hat Methoden, nicht nur Eigenschaften.
console.log("Hat die Klasse:", absatz.classList.contains("hinweis"));

// document ist der Einstiegspunkt in den ganzen Baum.
console.log("Titel:", document.title);
console.log("Wurzel:", document.documentElement.tagName);

Wenn der Browser eine HTML-Datei lädt, liest er sie einmal von oben nach unten und baut daraus einen Baum aus Objekten. Aus <p class="hinweis">Willkommen</p> wird ein Objekt mit Eigenschaften wie tagName, textContent und className, dazu Methoden wie classList.contains.

Dieser Baum heißt DOM, Document Object Model. Das Wort klingt größer, als die Sache ist: es sind Objekte und Arrays, so wie in Abschnitt 6 und 7, nur dass sie der Browser anlegt und nicht du.

document ist der Einstiegspunkt. Von dort kommst du an jedes Element der Seite, und alles, was in diesem Abschnitt kommt, beginnt mit diesem Wort.

Eltern, Kinder, Geschwister

Der Baum
const karten = document.querySelector(".karten");

// Kinder, Eltern, Geschwister. Jedes Element kennt seine Nachbarn.
console.log("Eltern:", karten.parentElement.tagName);
console.log("Anzahl Kinder:", karten.children.length);
console.log("Erstes Kind:", karten.firstElementChild.tagName);

// Und von unten nach oben geht es genauso.
const zweiteUeberschrift = document.querySelectorAll("h2")[1];
console.log("Text:", zweiteUeberschrift.textContent);
console.log("Eltern davon:", zweiteUeberschrift.parentElement.tagName);
console.log("Und deren Eltern:", zweiteUeberschrift.parentElement.parentElement.className);

// Ganz oben steht immer document.
console.log("body:", document.body.tagName);
console.log("head:", document.head.tagName);

Ein Baum heißt es, weil die Elemente ineinanderstecken. Ein <article> liegt in einem <div>, das im <body> liegt, der im <html> liegt. Und jedes Element kennt seine Nachbarschaft: sein parentElement, seine children, seine Geschwister.

Damit kannst du dich in beide Richtungen bewegen. Von oben nach unten über die Kinder, von unten nach oben über die Eltern. Lektion 10.3 zeigt das im Einzelnen, hier reicht die Vorstellung.

Ganz oben stehen immer dieselben drei: document, darunter document.documentElement (das ist <html>), darunter document.head und document.body. Die drei gibt es in jeder Seite, auch wenn sie im Markup gar nicht dastehen.

Und jetzt der wichtige Satz

Das DOM ist nicht die Datei
const absatz = document.querySelector("p");
console.log("Vorher:", absatz.textContent);

// Das hier ändert das DOM. Die Seite zeigt es sofort.
absatz.textContent = "Das hat JavaScript geschrieben.";
console.log("Nachher:", absatz.textContent);

// In der Datei links steht weiterhin der alte Satz. Sieh nach.
// Und beim nächsten Laden ist der alte Satz wieder da.

// Auch neue Elemente entstehen nur im DOM.
const neu = document.createElement("p");
neu.textContent = "Diesen Absatz gibt es in der Datei nicht.";
document.body.append(neu);

console.log("Absätze jetzt:", document.querySelectorAll("p").length);

Das DOM ist nicht die HTML-Datei. Es ist das, was der Browser daraus gemacht hat, und danach sind die beiden getrennt.

Änderst du mit JavaScript etwas am DOM, ändert sich die Seite sofort. Die Datei bleibt, wie sie ist. Beim nächsten Laden baut der Browser den Baum neu aus der Datei, und alles, was dein Skript getan hatte, ist weg.

Das ist keine Einschränkung, sondern die Grundlage. Eine Seite, die auf Klicks reagiert, verändert dabei ständig ihren Baum, und niemand will, dass sie dabei ihre eigene Datei umschreibt. Wer etwas wirklich behalten will, braucht Abschnitt 16 oder 17.

Im Beispiel siehst du beides nebeneinander: die Seite im Reiter Browser zeigt den neuen Satz, die Datei im Editor den alten. Das ist kein Fehler, das ist der Punkt.

Der Browser repariert dabei

Was der Browser noch dazutut
// Der Absatz oben hat kein schließendes Tag. Der Browser
// ergänzt es beim Bauen des Baums.
console.log("Absätze:", document.querySelectorAll("p").length);

// Und in die Tabelle hat er ein tbody eingezogen,
// obwohl im Markup keines steht.
console.log("tbody:", document.querySelectorAll("tbody").length);
console.log("Weg zur Zelle:", document.querySelector("td").parentElement.parentElement.tagName);

// Deshalb ist der Baum nicht die Datei. Frag ihn selbst:
// tipp die beiden Zeilen oben in die Eingabezeile der Console.

Beim Bauen des Baums nimmt der Browser es mit deinem Markup nicht ganz wörtlich. Ein fehlendes schließendes Tag ergänzt er, eine Tabelle bekommt ein <tbody>, auch wenn keines dasteht, und falsch verschachtelte Elemente rückt er zurecht.

Das kannst du nachfragen, statt es zu glauben. Tipp in die Eingabezeile der Console unter den Zeilen:

document.querySelectorAll("tbody").length

Die Antwort ist 1, obwohl im Markup links kein tbody steht. Und document.querySelector("td").parentElement.parentElement.tagName antwortet "TBODY": der Weg von der Zelle nach oben führt durch ein Element, das du nie geschrieben hast.

Praktisch heißt das vor allem eines: such den Weg zu einem Element nicht im Kopf zusammen, sondern frag den Baum. Was in der Datei steht, ist die Vorlage. Was dein JavaScript vorfindet, ist das Ergebnis, und die beiden sind nicht dasselbe.

Im echten Browser kommt dafür noch ein zweiter Weg dazu: die Entwicklerwerkzeuge zeigen unter „Elements” den fertigen Baum zum Aufklappen, und dort siehst du das eingefügte tbody einfach dastehen. Das ist der eine Blick, den die Console nicht ersetzt. Sie beantwortet Fragen, die du stellst, und zeigt dir nichts, wonach du nicht gefragt hast.

Zum Mitnehmen

Das DOM ist nicht die HTML-Datei, sondern das, was der Browser daraus gemacht hat. Deshalb ist nach dem Neuladen alles wieder wie vorher.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.