Javascript DOM (Document Object Model)

HTML als DOM tree

Das DOM beschreibt HTML-, XML- und SVG-Dokumente und 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: Datentypen, Funktionen) von Javascript festlegt, untersteht das DOM dem W3C.

23-02-02 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 eine eigene Schnittstelle im Document Object Model, an der JavaScript die Eigenschaften (i.d.R. Attribute des HTML-Elements) und Methoden definiert.

<input type="search" placeholder="Suche" id="search">
<section>
	<h1>Section<h1>
</sectuib>

Im DOM spiegelt sich das HTML wieder durch eine Anweisung wie

const searchBox = document.getElementById ("search");
const h1 = document.querySelector ("section h1")

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

querySelector ist eine Methode, die einen CSS-Selector – section h1 – nutzt, um ein HTML-Element mit Javascript zu ändern.

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 HTML-Elemente, 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.

<p id="toc" style="font-size:larger; text-align:center">CSS mit Javascript ändern </p>
<div class="demo">
	<button id="change">Schrift ändern</button>
</div>

CSS mit Javascript ändern

Schrift ändern
var count = 0;
document.getElementById('change').onclick = function () {
	if (count == 0) {
		document.getElementById('toc').setAttribute('style','font-family: Georgia,Times, serif; font-size:larger; text-align:center');
		count = count + 1;
	} else	if (count == 1) {
		document.getElementById('toc').setAttribute('style','font-family: Arial, Helvetica, sans-serif; font-size:larger; text-align:center');
		count = 0;
	}
}

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 setzen

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 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 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.

Heute haben wir darüber hinaus Abkürzungen wie elem.closest() und die ganz schnelle Truppe elem.querySelector() bzw. elem.querySelectorAll(), die ihre Ziele effizient und sicherer erreichen.

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.

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.

const myid = document.getElementById("MyId");
const selected = document.querySelector("#elem");
const elems = document.querySelectorAll(".item");