JavaScript/DOM
Das DOM (Document Object Model) ist die Schnittstelle zwischen HTML und dynamischem JavaScript. Alle Elemente werden zu Objekten, die dynamisch aufgerufen, verändert, hinzugefügt und gelöscht werden können.
Objektübersicht
- EventTarget
- Node
- Document (forms, elements)
- DocumentFragment
- Element (abstrakt)
- Attr (Attribut-Node)
- CharacterData (abstrakt)
- Text
- Comment (Kommentare)
- AbortSignal
- Event
- Range
- Selection
Allgemeines
Eine Webseite liegt dem Browser zunächst als bloßer Text, der mit der Auszeichnungssprache HTML formatiert ist, vor. Noch während der Browser den Code über das Netz empfängt, verarbeitet er ihn Stück für Stück. Diese Aufgabe übernimmt der sogenannte Parser (englisch parse = einen Satz in seine grammatikalischen Einzelteile zerlegen).
Der Parser überführt den HTML-Code in eine Objektstruktur, die dann im Arbeitsspeicher vorgehalten wird. Diese Objektstruktur besteht aus verschachtelten Knoten, allen voran Elementknoten, Attributknoten und Textknoten, die in einer Baumstruktur angeordnet sind.
Der Browser nutzt für alle weiteren Operationen diese Objektstruktur, nicht den HTML-Quellcode, an dem der Webautor üblicherweise arbeitet. Insbesondere CSS und JavaScript beziehen sich nicht auf den HTML-Code als Text, sondern auf den entsprechenden Elementenbaum im Speicher.
Die einzelnen Bestandteile einer solchen Baumstruktur werden als Knoten bezeichnet. Das zentrale Objekt des DOM ist deshalb das Objekt Node (node = Knoten). Es gibt verschiedene Knotentypen. Innerhalb eines gewöhnlichen HTML-Dokuments gibt es auf jeden Fall drei wichtige Knotentypen, die Sie unterscheiden müssen:
- Elementknoten
- Attributknoten
- Textknoten
DOM-Methoden
Dieser Elementenbaum ist jedoch nicht statisch, sondern kann durch DOM-Manipulation ausgelesen, verändert und erweitert werden.
Diese Methoden des document-Objekts ermöglichen es, auf jeden beliebigen Elementknoten direkt zuzugreifen:
- getElementById(): kann auf Elemente zugreifen, die ein dokumentweit eindeutiges id-Attribut enthalten
- getElementsByName(): kann auf Elemente zugreifen, die einen Namen besitzen (er muss nicht unbedingt eindeutig sein)
- getElementsByTagName(): kann auf alle Elemente zugreifen in der Form: "liefere mir das 27. td-Element im Dokument".
- querySelector(): gibt das erste Element zurück, das dem angegebenen CSS-Selektor entspricht.
- querySelectorAll(): gibt eine Liste von Elementen zurück, die dem angegebenen CSS-Selektor (auch mehrere, durch Komma getrennte, Angaben möglich) entsprechen
Ausgehend von einem ermittelten Elementknoten lässt sich dann schnell auf dessen Attribute und Inhalt zugreifen.
DOM-Manipulation
Sie können aber auch mit JavaScript/DOM/Document/createElement ein Element neu erzeugen und dann mit
in den Elementenbaum einhängen.
- JavaScript/Tutorials/DOM
- ein primitiver HTML-Editor (Neue Knoten erzeugen und in Baumstruktur einhängen)
Whitespace
Wie im oberen Abschnitt schon erwähnt, sind Webseiten Text-Dateien, die zur besseren Übersicht oft durch Zeilenumbrüche und einrückende Leerzeichen formatiert werden. Dies stellt Sie manchmal vor ein Problem, da folgender Code nicht wie oben dargestellt geparst wird:
<main>
<h1>Überschrift</h1>
<p>
Textinhalt
<img src="bild.jpg" alt="">
</p>
<!-- Hier ist ein Kommentar -->
</main>
Tatsächlich ist es aber so, dass auch der Whitespace zwischen den HTML Elementen Text darstellt und in Form von Textknoten im DOM abgelegt wird. In Wirklichkeit sieht das DOM also so aus:
Diese Weißräume können nützlich sein. Ein HTML wie das nachfolgende zeigt eine Leerstelle zwischen Hallo und Welt, weil sich zwischen den beiden <span>
-Elementen ein Textknoten befindet, der einen Zeilenumbruch und zwei Leerstellen enthält.
<main>
<span>Hallo</span>
<span>Welt</span>
</main>
Oft wird Whitespace vom Browser aber auch tatsächlich ignoriert. Was ist zum Beispiel mit dem Whitespace-Bereich zwischen den <main>
- und <span>
-Tags? Wenn jegliches Whitespace als ein Leerzeichen dargestellt würde, dann müsste das Wort "Hallo" um ein Leerzeichen eingerückt angezeigt werden. Das wird es aber nicht. Grund dafür ist, dass Leerraum am Beginn und am Ende eines HTML Elements nicht dargestellt wird.
Das vorige Beispiel verwendete einen Inline-Kontext zur Darstellung (weil das die normale Anzeigeart von <span>
-Elementen ist), aber wenn Sie Blockelemente wie <div>
verwenden, entsteht ein Block-Kontext. Hier gelten weitere Regeln.
<main>
<div>Hallo</div> Du
<div>schöne</div>
<div>Welt</div>
</main>
Die Ausgabe wird 4 Zeilen enthalten:
Hallo Du schöne Welt
Das Whitespace zwischen den beiden letzten <div>
-Elementen wird unterdrückt, weil ein Block-Kontext vorliegt.
Whitespace kann aber auch stören. Wenn Sie eine Toolbar mit vielen nebeneinanderliegenden Buttons erzeugen möchten, und jeden Button auf eine eigene Zeile schreiben, würde der Whitespace der Zeilenumbrüche jeweils als eine störende Leerstelle zwischen den Buttons angezeigt.
Um das zu lösen, könnten Sie alle Buttons nebeneinander ins HTML schreiben. Oft genug wird eine solche Toolbar auch per JavaScript erzeugt, und wenn Sie die Buttons einfach nacheinander in ein <div>
einsetzen, befinden sich keine Textknoten zwischen ihnen.
Wenn Sie die Toolbar aber als HTML im Editor erstellen, ist diese Notation schwer lesbar. Früher wurde empfohlen, die schließende spitze Klammer des </button>
-Tags in die Folgezeile zu schreiben, direkt vor das nächste <button>
-Tag. Das ist aber fehleranfällig. Es gibt auch den Vorschlag, den Whitespace in einen HTML Kommentar einzuschließen. Das ist auch nicht schön. Die korrekte Lösung ist, den standardmäßigen Inline-Kontext durch einen anderen zu ersetzen, indem Sie das Containerelement für die Buttons als Flexbox oder Grid darstellen.
Baumreihenfolge
Der Begriff der Baumreihenfolge (tree order) der Elemente im DOM ist zuweilen von Bedeutung. Es gibt in der Informatik drei wichtige Algorithmen, um eine Baumstruktur, wie sie das DOM darstellt, zu durchlaufen. Einer davon ist die Tiefensuche (englich pre-order traversal), bei der für jeden Knoten im Baum der Nachfolger in der Durchlaufreihenfolge so bestimmt wird, dass zunächst geschaut wird, ob er Kindelemente hat. Wenn ja, wird mit dem ersten Kindelement fortgesetzt. Erst, wenn alle Kindelemente durchlaufen sind, wird mit seinen Geschwisterelementen weitergemacht. Die Baumreihenfolge der Elemente in dem Beispieldokuments zu Beginn des Artikels wäre deshalb
<html>
, <head>
, <title>
, <meta>
, <body>
, <nav>
, <ul>
, <li>
, <a>
, <li>
, <a>
, <main>
, <h1>
, <p>
, <img>
.
Siehe auch
- JavaScript/Tutorials/DOM
- ein primitiver HTML-Editor (Neue Knoten erzeugen und in Baumstruktur einhängen)
Weblinks
- W3C: DOM
- MDN: Document Object Model (DOM)
- MDN: Über das Document Object Model