Javascript DOM (Document Object Model)

Javascript DOM Document Object Model: HTML Tags werden Javascript Elemente, HTML Attribute werden Eigenschaften von Elementen.

Das DOM (Document Object Model) beschreibt HTML-, XML- und SVG-Dokumente. Das DOM ist die Schnittstelle für den Zugriff auf HTML-Elemente, Attribute und Inhalte von HTML-Seiten, XML-Dokumenten und SVG-Grafiken.

Während ECMAScript die Grundlagen (Javascript Basis: Arrays, Strings, …, Methoden) von Javascript festlegt, wird das DOM vom W3C definiert und ist der Teil von Javascript, der die Dynamik ins Spiel bringt.

18-12-15 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

DOM – Verbindung zwischen Javascript und HTML

<table> oder <div class="expert"> sind HTML-Elemente in einem HTML-Dokument. HTML-Elemente haben Attribute, die ihr Verhalten bestimmen.

Das DOM verbindet Javascript mit den HTML-Elementen und erzeugt eine Baumstruktur, in der jedes HTML-Element eindeutig erreicht wird.

DOM Tree Nodes, parentNode, childNode, siblings, nextSibling
DOM Tree Nodes, parentNode, childNode, siblings, nextSibling

Jedes HTML-Element hat seine eigene Schnittstelle im Document Object Model, die Eigenschaften (i.d.R. Attribute des HTML-Elements) und Methoden für Javascript definiert.

<input type="search" placeholder="Suche" id="search">

Im DOM spiegelt sich das HTML wieder durch eine Anweisung wie

const searchBox = document.getElementById("search");

Mit searchBox hat Javascript Zugriff auf Eigenschaften, z.B. auf searchBox.value, und kann den Mauszeiger in das Eingabefeld setzen: searchBox.focus().

Eine Baumstruktur setzt alle Elemente eines Dokuments in Beziehung zueinander: Ein Dokument besteht aus Nodes (Knoten) in einer hierarchischen Baumstruktur. Javascript kann sich von einem Element aus durch die Seite hangeln und Elemente, Attribute oder Inhalt einfügen und entfernen.

An der Spitze des DOM-Baums sitzt das document-Objekt, gefolgt vom Root (der Wurzel des DOM-Baums), das bei Webseiten das html-Element der Seite ist. Unterhalb des html-Elements liegen das HEAD- und das BODY-Element.

CSS mit Javascript ändern

Die Methoden und Eigenschaften des DOM erzeugen neue Tags, manipulieren die Attribute, hängen Elemente mitsamt allen verschachtelten Elementen an eine andere Stelle des Dokuments und steuern den Fluss der Ereignisse, wenn das Dokument bereits im Fenster des Benutzers geladen ist und ersparen das aufwändige Neuladen des Dokuments.

Die komfortabelste und sicherste Methode, ein HTML-Element in der Webseite zu finden und zu ändern, ist der direkte Zugriff über class und id. getElementById holt das HTML-Element per eindeutiger id, querySelector und querySelectorAll sprechen sowohl ids als auch Klassen an.

CSS mit Javascript ändern

Schrift ändern
document.getElementById('change').onclick = function () {
   elem.setAttribute('style','font-family: Georgia,Times, serif');
}

Das Script identifiziert den Button anhand des id-Attributs change und fängt ein onclick-Event auf dem Element ab. Beim Klick auf den Button fügt das Script ein style-Attribut in das Element elem ein.

Elemente dynamisch erzeugen und ins DOM einsetzen

createElement () erzeugt ein neues Element – z.B. als Reaktion auf eine Aktion des Benutzers. before () / after () hängen neue Elemente on the fly in Document Objekt.

button.addEventListener ("click", function () {
	let img = document.createElement ("img");
	img.src = "img/fruit.svg";
	document.querySelector(".action").before (img);
});

parentElement, children, nextElementSibling, previousElementSibling

Die Elemente des DOM werden als Nodes – Knoten – bezeichnet. Das html-Element ist das Eltern-Element (parentElement) des head- und des body-Elements. In diesem Beispiel hat head zwei Kinder: titel und meta.

Nicht nur HTML-Elemente bilden Knoten oder DOM-Nodes, sondern HTML-Attribute und Inhalte und selbst Kommentare sind ebenfalls Elemente des DOM.

DOM mit parent, children, siblings
DOM Tree Nodes, parentNode, childNode, siblings, nextSibling und previousSibling

title und meta sind Nachkommen desselben Eltern-Elements – Siblings im Jargon des DOM. nav ist das Child – ein Kind und direkter Nachkomme von body. body wiederum ist Parent – Elternknoten – des nav-Elements.

Über die Beziehungen wie parentElementchildren, nextElementSibling und previousElementSibling erreicht Javascript jedes Element und kann neue Elemente erzeugen, in den Baum einhängen oder Teile des DOM-Baums löschen.

Zum HTML-Element durch das DOM

Ganz schön viele Zeiger für jedes Element im HTML-Dokument:

Zum DOM-Node über HTML-Elemente
Zum DOM-Node über HTML-Elemente

Kommentare, Leerzeichen zwischen den HTML-Tags und Zeilenumbrüche erzeugen ebenfalls Knoten, von denen wir lieber gar nichts wissen wollen. Darum wurde die Menge der Zeiger um echte Element-Nodes ergänzt: children, parentElement, firstElementChild, lastElementChild, previousElementSibling, nextElementSibling.

Damit reichen schon zwei Zeiger oder Referenzen, um alle Elemente im DOM zu erreichen.

function log (node) {
	console.log (node.nodeName)
}

function domWalker (node, func) {
	func(node);
	node = node.firstElementChild;
	while(node) {
		domWalker (node, func);
		node = node.nextElementSibling;
	}
}
domWalker (document.querySelector("BODY"), log);

// Quelle Douglas Crockford Vortragsnotizen

Einfacher als komplizierte while-Schleifen durchquert die rekursive Funktion domWalker alle Knoten des DOMs. Das zweite Argument ist eine Funktion, die in diesem Beispiel einfach nur den NodeName ausgibt.

Zum Glück müssen wir diese Sippschaft von Vorfahren, Nachkommen und Geschwister nicht verwalten: Die Browser bauen das Dokument als DOM-Baum aus HTML-Elementen, -Attributen und Inhalten auf und halten bei allen Änderungen immer die aktuellen Referenzen bereit.

Grundlage für funktionierende Skripte ist valides HTML.

Javascript Nodes: Leerraum, Weißraum, Kommentare

Aus den Anfängen des DOM finden wir Scripts von Methusalem veraltete Methoden wie nextSibling und previousSibling, die auch Leerraum durch Leerzeichen, Tabulatoren und Zeilenumbrüche als Knoten im DOM-Baum interpretieren. Da man sich auf den HTML-Quelltext nicht verlassen darf, müssen bei den alten Methoden die Rückgaben auf den Node Type geprüft werden.

querySelector, querySelectorAll

Auch die modernen Methoden wie nextElementSibling und previousElementSibling werden selten gebraucht, es ist aber auch kein Fehler, mal einen Blick drauf zu werfen.

Ein Element mit einem id-Attribut oder alle Elemente mit einer CSS-Klasse findet Javascript ohne Umwege.

let elem = document.getElementById("elem");
let elem = document.querySelector("#elem");
let elems = document.querySelectorAll(".item");