Document Object Model (DOM)
Das Document Object Model (DOM) verbindet Webseiten mit Skripten oder Programmiersprachen, indem es die Struktur eines Dokuments – wie das HTML einer Webseite – im Speicher darstellt. In der Regel bezieht es sich auf JavaScript, auch wenn die Modellierung von HTML-, SVG- oder XML-Dokumenten als Objekte nicht zum Kern der JavaScript-Sprache gehört.
Das DOM stellt ein Dokument als logischen Baum dar. Jeder Zweig des Baumes endet in einem Knoten, und jeder Knoten enthält Objekte. DOM-Methoden ermöglichen den programmatischen Zugriff auf den Baum. Mit ihnen können Sie die Struktur, den Stil oder den Inhalt des Dokuments ändern.
Knoten können auch Ereignishandler haben, die an sie angehängt sind. Sobald ein Ereignis ausgelöst wird, werden die Ereignishandler ausgeführt.
Konzepte und Nutzung
Das Document Object Model (DOM) ist eine Programmierschnittstelle für Webdokumente. Es stellt die Seite so dar, dass Programme die Dokumentstruktur, den Stil und den Inhalt ändern können. Das DOM stellt das Dokument als Knoten und Objekte dar; auf diese Weise können Programmiersprachen mit der Seite interagieren.
Eine Webseite ist ein Dokument, das entweder im Browserfenster angezeigt oder als HTML-Quelle dargestellt werden kann. In beiden Fällen ist es dasselbe Dokument, aber die Domänedarstellung ermöglicht es, es zu manipulieren. Als objektorientierte Darstellung der Webseite kann es mit einer Skriptsprache wie JavaScript modifiziert werden.
Zum Beispiel definiert das DOM, dass die querySelectorAll-Methode in diesem Code-Snippet eine Liste aller <p>-Elemente im Dokument zurückgeben muss:
const paragraphs = document.querySelectorAll("p");
// paragraphs[0] is the first <p> element
// paragraphs[1] is the second <p> element, etc.
alert(paragraphs[0].nodeName);
Alle Eigenschaften, Methoden und Ereignisse, die zur Manipulation und Erstellung von Webseiten verfügbar sind, sind in Objekte organisiert. Zum Beispiel ist das document-Objekt, das das Dokument selbst repräsentiert, jedes table-Objekt, das die HTMLTableElement DOM-Schnittstelle zur Zugriff auf HTML-Tabellen implementiert, und so weiter, alles Objekte.
Das DOM wird mit mehreren APIs erstellt, die zusammenarbeiten. Der Kern-DOM definiert die Entitäten, die ein beliebiges Dokument und die darin enthaltenen Objekte beschreiben. Diese werden nach Bedarf von anderen APIs erweitert, die neue Funktionen und Fähigkeiten zum DOM hinzufügen. Zum Beispiel fügt die HTML DOM API Unterstützung für die Darstellung von HTML-Dokumenten hinzu, und die SVG-API fügt Unterstützung für die Darstellung von SVG-Dokumenten hinzu.
Was ist ein DOM-Baum?
Ein DOM-Baum ist eine Baumstruktur, deren Knoten den Inhalt eines HTML- oder XML-Dokuments darstellen. Jedes HTML- oder XML-Dokument hat eine DOM-Baum-Darstellung. Betrachten Sie zum Beispiel das folgende Dokument:
<html lang="en">
<head>
<title>My Document</title>
</head>
<body>
<h1>Header</h1>
<p>Paragraph</p>
</body>
</html>
Es hat einen DOM-Baum, der so aussieht:

Obwohl der obige Baum dem DOM-Baum des obigen Dokuments ähnlich ist, sind sie nicht identisch, da der tatsächliche DOM-Baum Leerraum bewahrt.
Wenn ein Webbrowser ein HTML-Dokument analysiert, erstellt er einen DOM-Baum und verwendet ihn dann, um das Dokument anzuzeigen.
DOM und JavaScript
Das vorherige kurze Beispiel, wie fast alle Beispiele, ist JavaScript. Das heißt, es ist in JavaScript geschrieben, verwendet aber das DOM, um auf das Dokument und seine Elemente zuzugreifen. Das DOM ist keine Programmiersprache, aber ohne es hätte die JavaScript-Sprache kein Modell oder keine Vorstellung von Webseiten, HTML-Dokumenten, SVG-Dokumenten und ihren Bestandteilen. Das gesamte Dokument, der Kopf, Tabellen im Dokument, Tabellenköpfe, Text in den Tabellenzellen und alle anderen Elemente in einem Dokument sind Teile des Document Object Model für dieses Dokument. Sie können alle mit dem DOM und einer Skriptsprache wie JavaScript angegriffen und manipuliert werden.
Das DOM ist kein Teil der JavaScript-Sprache, sondern eine Web-API, die zum Erstellen von Webseiten verwendet wird. JavaScript kann auch in anderen Kontexten verwendet werden. Zum Beispiel führt Node.js JavaScript-Programme auf einem Computer aus, bietet jedoch eine andere Reihe von APIs, und die DOM-API ist kein Kernteil der Node.js-Laufzeitumgebung.
Das DOM wurde so konzipiert, dass es unabhängig von einer bestimmten Programmiersprache ist und die strukturelle Darstellung des Dokuments über eine einheitliche API verfügbar macht. Auch wenn die meisten Webentwickler das DOM nur über JavaScript verwenden, können Implementierungen des DOM für jede Sprache erstellt werden, wie dieses Python-Beispiel zeigt:
# Python DOM example
import xml.dom.minidom as m
doc = m.parse(r"C:\Projects\Py\chap1.xml")
doc.nodeName # DOM property of document object
p_list = doc.getElementsByTagName("para")
Für mehr Informationen über die Technologien, die beim Schreiben von JavaScript im Web involviert sind, sehen Sie die JavaScript-Technologien Übersicht.
Zugriff auf das DOM
Sie müssen nichts Besonderes tun, um das DOM zu verwenden. Sie nutzen die API direkt in JavaScript innerhalb eines Skripts, eines Programms, das von einem Browser ausgeführt wird.
Wenn Sie ein Skript erstellen, sei es inline in einem <script>-Element oder in die Webseite eingebunden, können Sie sofort beginnen, die API für die document- oder window-Objekte zu verwenden, um das Dokument selbst oder eines der verschiedenen Elemente auf der Webseite (die Nachkommenselemente des Dokuments) zu manipulieren. Ihre DOM-Programmierung kann so einfach wie das folgende Beispiel sein, das eine Nachricht in der Konsole anzeigt, indem die console.log()-Funktion verwendet wird:
<body onload="console.log('Welcome to my home page!');">
…
</body>
Da es im Allgemeinen nicht empfohlen wird, die Struktur der Seite (geschrieben in HTML) und die Manipulation des DOM (geschrieben in JavaScript) zu mischen, werden die JavaScript-Teile hier zusammengefasst und von dem HTML getrennt gehalten.
Zum Beispiel erstellt die folgende Funktion ein neues h1-Element, fügt diesem Element Text hinzu und fügt es dann in den Baum des Dokuments ein:
<html lang="en">
<head> </head>
<body>
<script>
// create a couple of elements in an otherwise empty HTML page
const heading = document.createElement("h1");
const headingText = document.createTextNode("Big Head!");
heading.appendChild(headingText);
document.body.appendChild(heading);
</script>
</body>
</html>
DOM-Schnittstellen
Die folgenden Schnittstellen sind alle durch die DOM-Spezifikation definiert:
AbortControllerAbortSignalAbstractRangeAttrCDATASectionCharacterDataCommentCustomEventDocumentDocumentFragmentDocumentTypeDOMErrorVeraltetDOMExceptionDOMImplementationDOMParserDOMTokenListElementEventEventTargetHTMLCollectionMutationObserverMutationRecordNamedNodeMapNodeNodeIteratorNodeListProcessingInstructionQuotaExceededErrorRangeShadowRootStaticRangeTextTreeWalkerXMLDocumentXPathEvaluatorXPathExpressionXPathResultXSLTProcessor
Dieser Leitfaden befasst sich mit den Objekten und den tatsächlichen Dingen, die Sie verwenden können, um die DOM-Hierarchie zu manipulieren. Es gibt viele Punkte, an denen das Verständnis wie diese funktionieren, verwirrend sein kann. Zum Beispiel erhält das Objekt, das das HTML-form-Element repräsentiert, seine Eigenschaft name von der HTMLFormElement-Schnittstelle, aber seine Eigenschaft className von der HTMLElement-Schnittstelle. In beiden Fällen ist die Eigenschaft, die Sie möchten, in diesem Formularobjekt.
Aber die Beziehung zwischen Objekten und den Schnittstellen, die sie im DOM implementieren, kann verwirrend sein. Daher versucht dieser Abschnitt ein wenig über die tatsächlichen Schnittstellen in der DOM-Spezifikation zu sagen und wie sie verfügbar gemacht werden.
Schnittstellen und Objekte
Viele Objekte implementieren mehrere verschiedene Schnittstellen. Das table-Objekt implementiert beispielsweise eine spezialisierte HTMLTableElement-Schnittstelle, die Methoden wie createCaption und insertRow umfasst. Aber da es auch ein HTML-Element ist, implementiert table die Element-Schnittstelle, die im DOM-Referenzkapitel Element beschrieben wird. Und da ein HTML-Element, soweit es DOM betrifft, auch ein Knoten im Baum der Knoten ist, die das Objektmodell für eine HTML- oder XML-Seite bilden, implementiert das table-Objekt auch die fundamentalere Node-Schnittstelle, von der Element ableitet.
Wenn Sie eine Referenz auf ein table-Objekt erhalten, wie im folgenden Beispiel, verwenden Sie routinemäßig alle drei dieser Schnittstellen im Hintergrund auf dem Objekt, vielleicht ohne es zu wissen.
const table = document.getElementById("table");
const tableAttrs = table.attributes; // Node/Element interface
for (const attr of tableAttrs) {
// HTMLTableElement interface: border attribute
if (attr.nodeName.toLowerCase() === "border") {
table.border = "1";
}
}
// HTMLTableElement interface: summary attribute
table.summary = "note: increased border";
Fundamentale Datentypen
Diese Seite versucht, die verschiedenen Objekte und Typen in einfachen Begriffen zu beschreiben. Aber es gibt eine Reihe von verschiedenen Datentypen, die innerhalb der API hin- und hergereicht werden, deren Sie sich bewusst sein sollten.
Hinweis: Da sich der Großteil des Codes, der das DOM verwendet, um die Manipulation von HTML-Dokumenten dreht, ist es üblich, auf die Knoten im DOM als Elemente zu verweisen, obwohl streng genommen nicht jeder Knoten ein Element ist.
Die folgende Tabelle beschreibt kurz diese Datentypen.
| Datentyp (Schnittstelle) | Beschreibung |
|---|---|
| [`Document`](/de/docs/Web/API/Document) |
Wenn ein Mitglied ein Objekt vom Typ document zurückgibt (z. B. die
ownerDocument-Eigenschaft eines Elements gibt das
document zurück, zu dem es gehört), ist dieses Objekt das
root document-Objekt selbst. Das
DOM document-Referenz-Kapitel beschreibt das document-Objekt.
|
| [`Node`](/de/docs/Web/API/Node) | Jedes im Dokument befindliche Objekt ist eine Knotenart. In einem HTML-Dokument kann ein Objekt ein Elementknoten, aber auch ein Textknoten oder Attributknoten sein. |
| [`Element`](/de/docs/Web/API/Element) |
Der element-Typ basiert auf node. Es bezieht
sich auf ein Element oder einen Knoten vom Typ element, den ein
Mitglied der DOM-API zurückgibt. Statt zu sagen, dass die
[`document.createElement()`](/de/docs/Web/API/Document/createElement)-Methode eine
Objektreferenz auf einen node zurückgibt, sagen wir einfach, dass diese Methode
das element zurückgibt, das gerade im DOM erstellt wurde.
Element-Objekte implementieren die DOM
Element-Schnittstelle und auch die grundlegendere
Node-Schnittstelle, die beide zusammen in dieser
Referenz enthalten sind. In einem HTML-Dokument werden Elemente weiter durch die
HTML DOM API's [`HTMLElement`](/de/docs/Web/API/HTMLElement)-Schnittstelle sowie
andere Schnittstellen beschrieben, die die Fähigkeiten spezifischer Arten von Elementen
beschreiben (beispielsweise [`HTMLTableElement`](/de/docs/Web/API/HTMLTableElement) für
<table>-Elemente).
|
| [`Attr`](/de/docs/Web/API/Attr) |
Wenn ein attribute von einem Mitglied zurückgegeben wird (z. B. durch die
Methode createAttribute()), ist es eine Objektreferenz, die
eine spezielle (wenn auch kleine) Schnittstelle für Attribute bereitstellt. Attribute
sind Knoten im DOM, genau wie Elemente, obwohl Sie sie möglicherweise
selten als solche verwenden.
|
Es gibt auch einige gängige terminologische Überlegungen, die Sie beachten sollten. Zum Beispiel ist es üblich, sich auf jeden Attr-Knoten als ein attribut zu beziehen und auf ein Array von DOM-Knoten als ein nodeList. Diese Begriffe und andere werden in der Dokumentation eingeführt und verwendet.
Die Objekte document und window sind die Objekte, deren Schnittstellen Sie im Allgemeinen am häufigsten in der DOM-Programmierung verwenden. Einfach ausgedrückt, repräsentiert das window-Objekt etwas wie den Browser und das document-Objekt die Wurzel des Dokuments selbst. Element erbt von der allgemeinen Node-Schnittstelle, und zusammen bieten diese beiden Schnittstellen viele der Methoden und Eigenschaften, die Sie an einzelnen Elementen verwenden. Diese Elemente können auch spezifische Schnittstellen für den Umgang mit der Art von Daten haben, die diese Elemente enthalten, wie im table-Objekt-Beispiel im vorherigen Abschnitt.
Obsolete DOM-Schnittstellen
Das Document Object Model wurde stark vereinfacht. Um dies zu erreichen, wurden die folgenden Schnittstellen in den verschiedenen Spezifikationen der DOM-Level-3 oder früher entfernt. Sie sind für Webentwickler nicht mehr verfügbar.
DOMConfigurationDOMErrorHandlerDOMImplementationListDOMImplementationRegistryDOMImplementationSourceDOMLocatorDOMObjectDOMSettableTokenListDOMUserDataElementTraversalEntityEntityReferenceNameListNotationTypeInfoUserDataHandler
HTML DOM
Ein Dokument, das HTML enthält, wird unter Verwendung der Document-Schnittstelle beschrieben, die durch die HTML-Spezifikation erweitert wird, um verschiedene HTML-spezifische Funktionen einzuschließen. Insbesondere wird die Element-Schnittstelle verbessert, um zu HTMLElement und verschiedenen Unterklassen zu werden, von denen jede ein (oder eine Familie eng verwandter) Elemente darstellt.
Die HTML DOM API bietet Zugriff auf verschiedene Browserfunktionen wie Tabs und Fenster, CSS-Stile und Stylesheets, Browserverlauf usw. Diese Schnittstellen werden weiter in der HTML DOM API-Dokumentation diskutiert.
SVG DOM
Ähnlich wird ein Dokument, das SVG enthält, auch unter Verwendung der Document-Schnittstelle beschrieben, die durch die SVG-Spezifikation erweitert wird, um verschiedene SVG-spezifische Funktionen einzuschließen. Insbesondere wird die Element-Schnittstelle verbessert, um zu SVGElement und verschiedenen Unterklassen zu werden, von denen jede ein Element oder eine Familie eng verwandter Elemente darstellt. Diese Schnittstellen werden weiter in der SVG API-Dokumentation diskutiert.
Beispiele
>Textinhalt setzen
Dieses Beispiel verwendet ein <div>-Element mit einem <textarea> und zwei <button>-Elementen. Wenn der Benutzer auf den ersten Button klickt, setzen wir einen Text in das <textarea>. Wenn der Benutzer auf den zweiten Button klickt, löschen wir den Text. Wir verwenden:
Document.querySelector(), um auf das<textarea>und den Button zuzugreifenEventTarget.addEventListener(), um Mausklicks zu überwachenNode.textContent, um den Text zu setzen und zu löschen.
HTML
<div class="container">
<textarea class="story"></textarea>
<button id="set-text" type="button">Set text content</button>
<button id="clear-text" type="button">Clear text content</button>
</div>
CSS
.container {
display: flex;
gap: 0.5rem;
flex-direction: column;
}
button {
width: 200px;
}
JavaScript
const story = document.querySelector(".story");
const setText = document.querySelector("#set-text");
setText.addEventListener("click", () => {
story.textContent = "It was a dark and stormy night...";
});
const clearText = document.querySelector("#clear-text");
clearText.addEventListener("click", () => {
story.textContent = "";
});
Ergebnis
Ein Kindelement hinzufügen
Dieses Beispiel verwendet ein <div>-Element mit einem <div> und zwei <button>-Elementen. Wenn der Benutzer auf den ersten Button klickt, erstellen wir ein neues Element und fügen es als Kind des <div> hinzu. Wenn der Benutzer auf den zweiten Button klickt, entfernen wir das Kindelement. Wir verwenden:
Document.querySelector(), um auf das<div>und die Tasten zuzugreifenEventTarget.addEventListener(), um Mausklicks zu überwachenDocument.createElement, um das Element zu erstellenNode.appendChild(), um das Kind hinzuzufügenNode.removeChild(), um das Kind zu entfernen.
HTML
<div class="container">
<div class="parent">parent</div>
<button id="add-child" type="button">Add a child</button>
<button id="remove-child" type="button">Remove child</button>
</div>
CSS
.container {
display: flex;
gap: 0.5rem;
flex-direction: column;
}
button {
width: 100px;
}
div.parent {
border: 1px solid black;
padding: 5px;
width: 100px;
height: 100px;
}
div.child {
border: 1px solid red;
margin: 10px;
padding: 5px;
width: 80px;
height: 60px;
box-sizing: border-box;
}
JavaScript
const parent = document.querySelector(".parent");
const addChild = document.querySelector("#add-child");
addChild.addEventListener("click", () => {
// Only add a child if we don't already have one
// in addition to the text node "parent"
if (parent.childNodes.length > 1) {
return;
}
const child = document.createElement("div");
child.classList.add("child");
child.textContent = "child";
parent.appendChild(child);
});
const removeChild = document.querySelector("#remove-child");
removeChild.addEventListener("click", () => {
const child = document.querySelector(".child");
parent.removeChild(child);
});
Ergebnis
Den Baum lesen und ändern
Nehmen wir an, der Autor möchte die Kopfzeile des Dokuments in Was ist ein DOM-Baum? ändern und zwei Absätze anstelle von einem schreiben. Das folgende Skript würde die Arbeit erledigen:
HTML
<html lang="en">
<head>
<title>My Document</title>
</head>
<body>
<input type="button" value="Change this document." />
<h2>Header</h2>
<p>Paragraph</p>
</body>
</html>
JavaScript
document.querySelector("input").addEventListener("click", () => {
// document.getElementsByTagName("h2") returns a NodeList of the <h2>
// elements in the document, and the first is number 0:
const header = document.getElementsByTagName("h2").item(0);
// The firstChild of the header is a Text node:
header.firstChild.data = "A dynamic document";
// Now header is "A dynamic document".
// Access the first paragraph
const para = document.getElementsByTagName("p").item(0);
para.firstChild.data = "This is the first paragraph.";
// Create a new Text node for the second paragraph
const newText = document.createTextNode("This is the second paragraph.");
// Create a new Element to be the second paragraph
const newElement = document.createElement("p");
// Put the text in the paragraph
newElement.appendChild(newText);
// Put the paragraph on the end of the document by appending it to
// the body (which is the parent of para)
para.parentNode.appendChild(newElement);
});
Erstellen eines Baumes
Sie können den Baum in Was ist ein DOM-Baum? auch vollständig in JavaScript erstellen.
const root = document.createElement("html");
root.lang = "en";
const head = document.createElement("head");
const title = document.createElement("title");
title.appendChild(document.createTextNode("My Document"));
head.appendChild(title);
const body = document.createElement("body");
const header = document.createElement("h1");
header.appendChild(document.createTextNode("Header"));
const paragraph = document.createElement("p");
paragraph.appendChild(document.createTextNode("Paragraph"));
body.appendChild(header);
body.appendChild(paragraph);
root.appendChild(head);
root.appendChild(body);
Ereignis-Weitergabe
Dieses Beispiel zeigt, wie Ereignisse im DOM auf sehr einfache Weise ausgelöst und behandelt werden. Wenn der BODY dieses HTML-Dokuments geladen wird, wird ein Ereignis-Listener bei der obersten Zeile der TABLE registriert. Der Ereignis-Listener behandelt das Ereignis, indem die Funktion stopEvent ausgeführt wird, die den Wert in der unteren Zelle der Tabelle ändert.
Allerdings ruft stopEvent auch eine Ereignisobjektmethode auf, event.stopPropagation, die verhindert, dass das Ereignis weiter nach oben in den DOM blubbert. Beachten Sie, dass die Tabelle selbst einen onclick-Ereignishandler hat, der eine Nachricht anzeigen sollte, wenn die Tabelle angeklickt wird. Aber die stopEvent-Methode hat die Weitergabe gestoppt, und so wird nach der Aktualisierung der Daten in der Tabelle die Ereignisphase effektiv beendet, und es wird ein Hinweisfenster angezeigt, um dies zu bestätigen.
<table id="t-daddy">
<tbody>
<tr id="tbl1">
<td id="c1">one</td>
</tr>
<tr>
<td id="c2">two</td>
</tr>
</tbody>
</table>
#t-daddy {
border: 1px solid red;
}
#c1 {
background-color: pink;
}
function stopEvent(event) {
const c2 = document.getElementById("c2");
c2.textContent = "hello";
// this ought to keep t-daddy from getting the click.
event.stopPropagation();
console.log("event propagation halted.");
}
const elem = document.getElementById("tbl1");
elem.addEventListener("click", stopEvent);
document.getElementById("t-daddy").addEventListener("click", () => {
console.log("t-daddy clicked");
});
Eigenschaften des Ereignisobjekts anzeigen
Dieses Beispiel verwendet DOM-Methoden, um alle Eigenschaften des click-Ereignisobjekts und ihre Werte in einer Tabelle anzuzeigen. Es zeigt auch eine nützliche Technik, eine for...in-Schleife zu verwenden, um über die Eigenschaften eines Objekts zu iterieren, um deren Werte zu erhalten.
Die Eigenschaften von Ereignisobjekten unterscheiden sich stark zwischen Browsern, der WHATWG DOM-Standard listet die Standard-Eigenschaften, jedoch haben viele Browser diese stark erweitert.
Fügen Sie den folgenden Code in eine leere Textdatei ein und laden Sie diese in verschiedenen Browsern, Sie werden überrascht sein über die unterschiedliche Anzahl und Namen der Eigenschaften. Sie könnten auch einige Elemente auf der Seite hinzufügen und diese Funktion von verschiedenen Ereignishandlern aufrufen.
<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
table {
border-collapse: collapse;
margin-top: 2em;
}
thead {
font-weight: bold;
}
td {
padding: 2px 10px;
}
.odd {
background-color: #efdfef;
}
.even {
background-color: white;
}
function showEventProperties(event) {
function addCell(row, text) {
const cell = row.insertCell(-1);
cell.appendChild(document.createTextNode(text));
}
document.getElementById("eventType").textContent = event.type;
const table = document.createElement("table");
const thead = table.createTHead();
let row = thead.insertRow(-1);
const labelList = ["#", "Property", "Value"];
const len = labelList.length;
for (let i = 0; i < len; i++) {
addCell(row, labelList[i]);
}
const tbody = document.createElement("tbody");
table.appendChild(tbody);
for (const p in event) {
row = tbody.insertRow(-1);
row.className = row.rowIndex % 2 ? "odd" : "even";
addCell(row, row.rowIndex);
addCell(row, p);
addCell(row, event[p]);
}
document.body.appendChild(table);
}
window.addEventListener("click", showEventProperties);
Spezifikationen
| Spezifikation |
|---|
| DOM> |