Document Object Model (DOM)
Das Document Object Model (DOM) verbindet Webseiten mit Skripten oder Programmiersprachen, indem es die Struktur eines Dokuments – wie das HTML, das eine Webseite repräsentiert – im Speicher darstellt. In der Regel bezieht es sich auf JavaScript, obwohl das Modellieren von HTML-, SVG- oder XML-Dokumenten als Objekte nicht Teil der Kernsprache von JavaScript ist.
Das DOM stellt ein Dokument als logischen Baum dar. Jeder Ast 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 zugeordnet sein. Sobald ein Ereignis ausgelöst wird, werden die Ereignishandler ausgeführt.
Konzepte und Verwendung
Das Document Object Model (DOM) ist eine Programmierschnittstelle für Webdokumente. Es stellt die Seite so dar, dass Programme die Dokumentstruktur, den Stil und 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 handelt es sich um dasselbe Dokument, aber die Darstellung im Document Object Model (DOM) erlaubt es, es zu manipulieren. Als objektorientierte Repräsentation der Webseite kann es mit einer Skriptsprache wie JavaScript modifiziert werden.
Zum Beispiel spezifiziert 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 verfügbaren Eigenschaften, Methoden und Ereignisse zur Manipulation und Erstellung von Webseiten sind in Objekten organisiert. Zum Beispiel das document
-Objekt, das das Dokument selbst darstellt, irgendwelche table
-Objekte, die die HTMLTableElement
DOM-Schnittstelle zur Zugriff auf HTML-Tabellen implementieren, und so weiter, sind alles Objekte.
Das DOM wird unter Nutzung mehrerer APIs aufgebaut, die zusammenarbeiten. Das Basis-DOM definiert die Entitäten, die jedes Dokument und die Objekte darin beschreiben. Dies wird nach Bedarf durch andere 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 zum Basis-DOM hinzu, und die SVG API fügt Unterstützung zur 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 repräsentieren. Jedes HTML- oder XML-Dokument hat eine DOM-Baumarstellung. Zum Beispiel betrachten Sie folgendes 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 Leerzeichen beibehält.
Wenn ein Webbrowser ein HTML-Dokument analysiert, baut er einen DOM-Baum und verwendet diesen, um das Dokument anzuzeigen.
DOM und JavaScript
Das vorhergehende kurze Beispiel, wie fast alle Beispiele, ist JavaScript. Das bedeutet, es ist in JavaScript geschrieben, aber verwendet das DOM, um auf das Dokument und seine Elemente zuzugreifen. Das DOM ist keine Programmiersprache, aber ohne sie hätte die JavaScript-Sprache kein Modell oder Konzept von Webseiten, HTML-Dokumenten, SVG-Dokumenten und deren Komponenten. Das Dokument als Ganzes, der Kopf, Tabellen innerhalb des Dokuments, Tabellenüberschriften, Text innerhalb der 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 zugegriffen und manipuliert werden.
Das DOM ist kein Teil der JavaScript-Sprache, sondern eine Web-API, die zum Bauen von Webseiten verwendet wird. JavaScript kann auch in anderen Kontexten verwendet werden. Zum Beispiel führt Node.js JavaScript-Programme auf einem Computer aus, stellt aber ein anderes Set von APIs bereit, und die DOM-API ist kein Kernbestandteil der Node.js-Laufzeitumgebung.
Das DOM wurde entwickelt, um unabhängig von einer bestimmten Programmiersprache zu sein und macht die strukturelle Darstellung des Dokuments aus einer einzigen, konsistenten API zugänglich. Auch wenn die meisten Webentwickler das DOM nur durch JavaScript nutzen, 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")
Weitere Informationen über die Technologien, die an der Erstellung von JavaScript im Web beteiligt sind, finden Sie im JavaScript-Technologieüberblick.
Zugreifen auf das DOM
Sie müssen nichts Besonderes tun, um mit der Verwendung des DOM zu beginnen. Sie verwenden 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 einbezogen, können Sie sofort beginnen, die API für die document
- oder window
-Objekte zu verwenden, um das Dokument selbst oder irgendeines der verschiedenen Elemente auf der Webseite (die Nachkommenselemente des Dokuments) zu manipulieren. Ihre DOM-Programmierung kann so einfach sein wie das folgende Beispiel, das eine Nachricht auf der Konsole anzeigt, indem die Funktion console.log()
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 vom HTML getrennt.
Zum Beispiel erstellt die folgende Funktion ein neues h1-Element, fügt diesem Element Text hinzu und fügt es dann dem Baum des Dokuments hinzu:
<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 sind alle von der DOM-Spezifikation definierten Schnittstellen:
AbortController
AbortSignal
AbstractRange
Attr
CDATASection
CharacterData
Comment
CustomEvent
Document
DocumentFragment
DocumentType
DOMError
VeraltetDOMException
DOMImplementation
DOMParser
DOMTokenList
Element
Event
EventTarget
HTMLCollection
MutationObserver
MutationRecord
NamedNodeMap
Node
NodeIterator
NodeList
ProcessingInstruction
QuotaExceededError
Range
ShadowRoot
StaticRange
Text
TreeWalker
XMLDocument
XPathEvaluator
XPathExpression
XPathResult
XSLTProcessor
Dieser Leitfaden behandelt die Objekte und die tatsächlichen Dinge, 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 darstellt, seine name
-Eigenschaft von der HTMLFormElement
-Schnittstelle, aber seine className
-Eigenschaft von der HTMLElement
-Schnittstelle. In beiden Fällen befindet sich die gewünschte Eigenschaft in diesem Formularelement.
Aber die Beziehung zwischen Objekten und den Schnittstellen, die sie im DOM implementieren, kann verwirrend sein, und so versucht dieser Abschnitt, ein wenig über die tatsächlichen Schnittstellen in der DOM-Spezifikation und wie sie bereitgestellt werden, zu erklären.
Schnittstellen und Objekte
Viele Objekte implementieren mehrere verschiedene Schnittstellen. Das Tabellenobjekt zum Beispiel implementiert eine spezialisierte HTMLTableElement
-Schnittstelle, die Methoden wie createCaption
und insertRow
enthält. Aber da es auch ein HTML-Element ist, implementiert table
die Element
-Schnittstelle, die im DOM-Reference-Kapitel von Element
beschrieben wird. Und schließlich, da ein HTML-Element auch, soweit es das DOM betrifft, ein Knoten im Baum der Knoten ist, die das Objektmodell für eine HTML- oder XML-Seite bilden, implementiert das Tabellenobjekt auch die grundlegendere Node
-Schnittstelle, von der Element
abgeleitet ist.
Wenn Sie eine Referenz auf ein table
-Objekt erhalten, wie im folgenden Beispiel, verwenden Sie routinemäßig alle drei dieser Schnittstellen austauschbar 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";
Grundlegende Datentypen
Diese Seite versucht, die verschiedenen Objekte und Typen in einfachen Worten zu beschreiben. Aber es gibt eine Reihe von verschiedenen Datentypen, die durch die API weitergegeben werden, die Ihnen bewusst sein sollten.
Hinweis: Da der größte Teil des Codes, der das DOM benutzt, sich um die Manipulation von HTML-Dokumenten dreht, ist es üblich, sich auf die Knoten im DOM als Elemente zu beziehen, obwohl streng genommen nicht jeder Knoten ein Element ist.
Die folgende Tabelle beschreibt diese Datentypen kurz.
Datentyp (Schnittstelle) | Beschreibung |
---|---|
[`Document`](/de/docs/Web/API/Document) |
Wenn ein Mitglied ein Objekt des Typs 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 Objekt, das sich innerhalb eines Dokuments befindet, ist eine Art von Knoten. 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 , der von einem
Mitglied der DOM-API zurückgegeben wird. Anstatt zu sagen, dass z.B. die
[`document.createElement()`](/de/docs/Web/API/Document/createElement)-Methode
eine Objekt-Referenz zu einem 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 diesem
Referenzdokument enthalten sind. In einem HTML-Dokument werden die Elemente durch die HTML-DOM-API
[`HTMLElement`](/de/docs/Web/API/HTMLElement)-Schnittstelle sowie
andere Schnittstellen, die die Fähigkeiten spezifischer Arten von Elementen beschreiben
(zum Beispiel [`HTMLTableElement`](/de/docs/Web/API/HTMLTableElement) für
<table> -Elemente), weiter verbessert.
|
[`Attr`](/de/docs/Web/API/Attr) |
Wenn ein attribute von einem Mitglied (z.B. von der
createAttribute() -Methode) zurückgegeben wird, ist es eine Objekt-Referenz, die
eine spezielle (wenn auch kleine) Schnittstelle für Attribute exponiert. Attribute
sind Knoten im DOM, genau wie Elemente, obwohl Sie sie vielleicht selten
als solche verwenden.
|
Es gibt auch einige allgemeine Begrifflichkeiten, die Sie beachten sollten. Es ist üblich, sich auf jeden Attr
-Knoten als ein Attribut
zu beziehen, zum Beispiel, und ein Array von DOM-Knoten als nodeList
zu bezeichnen. Sie werden feststellen, dass diese Begriffe und andere im gesamten Dokument eingeführt und verwendet werden.
Die document
- und window
-Objekte sind die Objekte, deren Schnittstellen Sie in der Regel am häufigsten in der DOM-Programmierung verwenden. Einfach gesagt, repräsentiert das window
-Objekt etwas wie den Browser, und das document
-Objekt ist das Root des Dokuments selbst. Element
erbt von der generischen Node
-Schnittstelle, und zusammen bieten diese beiden Schnittstellen viele der Methoden und Eigenschaften, die Sie bei Einzelnen Elementen verwenden können. Diese Elemente können auch spezifische Schnittstellen haben, um mit der Art von Daten umzugehen, die diese Elemente halten, wie im table
-Objekt-Beispiel im vorhergehenden Abschnitt beschrieben.
Veraltete DOM-Schnittstellen
Das Document Object Model wurde stark vereinfacht. Um dies zu erreichen, wurden die folgenden Schnittstellen in den verschiedenen DOM-Level-3- oder früheren Spezifikationen entfernt. Sie stehen Webentwicklern nicht mehr zur Verfügung.
DOMConfiguration
DOMErrorHandler
DOMImplementationList
DOMImplementationRegistry
DOMImplementationSource
DOMLocator
DOMObject
DOMSettableTokenList
DOMUserData
ElementTraversal
Entity
EntityReference
NameList
Notation
TypeInfo
UserDataHandler
HTML DOM
Ein Dokument, das HTML enthält, wird unter Verwendung der Document
-Schnittstelle beschrieben, die von der HTML-Spezifikation erweitert wird, um verschiedene HTML-spezifische Funktionen einzuschließen. Insbesondere wird die Element
-Schnittstelle erweitert, um HTMLElement
und verschiedene Unterklassen zu werden, die jeweils ein Element oder eine Familie von verwandten Elementen darstellen.
Die HTML-DOM-API bietet Zugriff auf verschiedene Browser-Funktionen wie Tabs und Fenster, CSS-Stile und Stylesheets, Browser-Verlauf, etc. Diese Schnittstellen werden weiter in der HTML-DOM-API-Dokumentation diskutiert.
SVG DOM
Ebenso wird ein Dokument, das SVG enthält, auch unter Verwendung der Document
-Schnittstelle beschrieben, die von der SVG-Spezifikation erweitert wird, um verschiedene SVG-spezifische Funktionen einzuschließen. Insbesondere wird die Element
-Schnittstelle erweitert, um SVGElement
und verschiedene Unterklassen zu werden, die jeweils ein Element oder eine Familie von verwandten Elementen darstellen. Diese Schnittstellen werden weiter in der SVG-API-Dokumentation diskutiert.
Beispiele
>Textinhalt setzen
Dieses Beispiel verwendet ein <div>
-Element, das ein <textarea>
und zwei <button>
-Elemente enthält. Wenn der Benutzer den ersten Button anklickt, setzen wir etwas Text in das <textarea>
. Wenn der Benutzer den zweiten Button anklickt, leeren wir den Text. Wir verwenden:
Document.querySelector()
, um auf das<textarea>
und die Schaltfläche zuzugreifenEventTarget.addEventListener()
, um Klicks der Schaltflächen zu überwachenNode.textContent
, um den Text zu setzen und zu leeren.
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.body.querySelector(".story");
const setText = document.body.querySelector("#set-text");
setText.addEventListener("click", () => {
story.textContent = "It was a dark and stormy night...";
});
const clearText = document.body.querySelector("#clear-text");
clearText.addEventListener("click", () => {
story.textContent = "";
});
Ergebnis
Hinzufügen eines Kindelements
Dieses Beispiel verwendet ein <div>
-Element, das ein <div>
und zwei <button>
-Elemente enthält. Wenn der Benutzer den ersten Button anklickt, erstellen wir ein neues Element und fügen es als Kind des <div>
hinzu. Wenn der Benutzer den zweiten Button anklickt, entfernen wir das Kindelement. Wir verwenden:
Document.querySelector()
, um auf das<div>
und die Schaltflächen zuzugreifenEventTarget.addEventListener()
, um Klicks der Schaltflächen 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.body.querySelector(".parent");
const addChild = document.body.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.body.querySelector("#remove-child");
removeChild.addEventListener("click", () => {
const child = document.body.querySelector(".child");
parent.removeChild(child);
});
Ergebnis
Lesen und Modifizieren des Baumes
Angenommen, der Autor möchte die Überschrift des Dokuments in Was ist ein DOM-Baum? ändern und zwei Absätze anstelle von einem schreiben. Das folgende Skript würde die Aufgabe 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);
Ereignisweiterleitung
Dieses Beispiel zeigt, wie Ereignisse auf sehr einfache Weise im DOM ausgelöst und verarbeitet werden. Wenn der BODY dieses HTML-Dokuments geladen wird, wird ein Ereignislistener mit der obersten Reihe der TABLE registriert. Der Ereignislistener behandelt das Ereignis, indem er die Funktion stopEvent ausführt, die den Wert in der unteren Zelle der Tabelle verändert.
Allerdings ruft stopEvent auch eine Ereignisobjektmethode auf, event.stopPropagation
, die verhindert, dass das Ereignis weiter im DOM propagiert. 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 Weiterleitung unterbrochen, und so wird, nachdem die Daten in der Tabelle aktualisiert wurden, die Ereignisphase effektiv beendet, und eine Alert-Box erscheint, um dies zu bestätigen.
<table id="t-daddy">
<tr id="tbl1">
<td id="c1">one</td>
</tr>
<tr>
<td id="c2">two</td>
</tr>
</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 onload
-event
-Objekts und deren 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 den Browsern; der WHATWG DOM Standard listet die Standard-Eigenschaften auf, viele Browser haben diese jedoch erheblich erweitert.
Setzen Sie den folgenden Code in eine leere Textdatei und laden Sie sie in eine Vielzahl von Browsern, Sie werden überrascht über die unterschiedliche Anzahl und Namen der Eigenschaften sein. Möglicherweise möchten Sie auch einige Elemente auf der Seite hinzufügen und diese Funktion von verschiedenen Ereignishandler aufrufen.
<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
table {
border-collapse: collapse;
}
thead {
font-weight: bold;
}
td {
padding: 2px 10px;
}
.odd {
background-color: #efdfef;
}
.even {
background-color: white;
}
function showEventProperties(e) {
function addCell(row, text) {
const cell = row.insertCell(-1);
cell.appendChild(document.createTextNode(text));
}
const event = e || window.event;
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);
}
showEventProperties(event);
Spezifikationen
Specification |
---|
DOM> |