JavaScript/DOM/Node

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Die Node-Schnittstelle (node = Knoten) ist das zentrale Objekt des Document Object Models (DOM). Es repräsentiert einen einzelnen Knoten in dem Objektbaum, in der Text eines HTML- oder XML-Dokuments übersetzt wird. Bei diesen Knoten kann es sich um Elemente handeln, aber Attribute, Text und das Dokument selbst sind ebenfalls spezielle Typen von Nodes. Für jeden Node-Typ gibt es eine von Node abgeleitete Schnittstelle, die Methoden oder Eigenschaften ergänzt.

Die im Folgenden aufgelisteten Eigenschaften und Methoden sind allen diesen Node-Typen gemeinsam.

Die möglichen Werte der nodeType-Eigenschaft finden sich als schreibgeschütze Eigenschaften mit Namen wie ELEMENT_NODE im Node-Objekt. Details dazu finden Sie bei der Beschreibung der nodeType-Eigenschaft.

Allgemeines

Hintergrund ist das Modell, dass sich ein Auszeichnungssprachen-Dokument, egal ob in HTML oder einer anderen, XML-basierten Auszeichnungssprache geschrieben, als eine Baumstruktur aus Knoten unterschiedlichen Typs darstellen lässt. Um sich mit diesem Modell näher zu beschäftigen, können Sie im XML-Kapitel dieses Dokuments den Abschnitt Baumstruktur und Knoten einer XML-Datei lesen.


DOM - Nodes im Elementenbaum
DOM - Nodes im Elementenbaum

Knotentypen

Innerhalb eines gewöhnlichen HTML-Dokuments gibt es mehrere wichtige Knotentypen, die Sie unterscheiden müssen:

  • Elementknoten
  • Attributknoten
  • Textknoten
  • Kommentare

Sie können die unterschiedlichen Typen mit Node.nodeType identifizieren.

Elementknoten

Das DOM enthält für jedes HTML Element einen Elementknoten. Die Programmierschnittstelle für HTML Elemente ist eine Erweiterung der Node-Schnittstelle, deshalb können Sie für einen solchen Knoten zusätzlich auch die Eigenschaften und Methoden der Schnittstellen Element und HTMLElement nutzen.

Attributknoten

Attributknoten wurden bei der Konzipierung des DOM von Node abgeleitet. Ihr Interface Attr erbt alle Eigenschaften und Methoden von Node, aber Attribute stellen aber keine allgemeinen Kind-Knoten im DOM-Baum dar. Nur Elemente können Attribute besitzen, deswegen findet sich in der Element-Schnittstelle die Eigenschaft attributes, die die Attribute dieses Elements enthält.

Versuchen Sie nicht, Eigenschaften oder Methoden der Node-Schnittstelle auf einen Attributknoten anzuwenden, und behandeln Sie Attribute einfach als Name-Wert Paare, die einem Element zugeordnet sind. Bei der Verarbeitung eines XML Dokuments sieht die Sache etwas anders aus, dort müssen Sie möglicherweise Namespaces behandeln. Sie sollten dann aber mit Namespace-Präfixen arbeiten und den qualifizierten Namen eines Attributs als seinen ganz normalen Namen auffassen.

Die Living Standard Spezifikation des Document Object Model enthält einen bezeichnenden Satz zur Attributen:

„Note: If designed today they would just have a name and value. ☹“

Knotentypen, die Text enthalten

Diese Knotentypen haben gemeinsam, dass sie das von Node abgeleitete CharacterData-Interface implementieren.

Textknoten
Normaler Text innerhalb von Textstrukturierungs- und Textauszeichnungselementen bildet Textknoten.
Kommentare
Kommentarknoten verwenden die von CharacterData abgeleitete Schnittstelle Comment, die aber keine eigenen Eigenschaften oder Methoden enthält.
Der Textinhalt innerhalb des Kommentars bildet keinen eigenen Textknoten.[1]

Verwendung

Jedes Element und alle Zeichendaten stellen eigene Knoten dar. Diese Knoten bilden die Baumstruktur. Das Node-Interface stellt Eigenschaften und Methoden bereit, um auf die einzelnen Knoten zuzugreifen, egal, wie tief diese Knoten in der Baumstruktur liegen.

Das Node-Interface stellt damit die allgemeinere und für alle XML-gerechten Sprachen gültige Variante dessen dar, was die HTML-Elementobjekte speziell für HTML darstellen. Sie können in JavaScript sowohl mit den HTML-Elementobjekten als auch mit dem Node-Interface arbeiten. Manches ist über die HTML-Elementobjekte bequemer zu lösen, für andere Aufgaben eignet sich wiederum das Node-Interface besser. Das Node-Objekt gilt unter Puristen allerdings als das "reinere" DOM, eben weil es nicht auf HTML beschränkt ist.

Um auf die Eigenschaften und Methoden des Node-Objekts zugreifen zu können, benötigen Sie einen Knoten. Um auf vorhandene Element-Knoten im Dokument zuzugreifen, verwenden Sie die Methoden des document-Objekts:

  • 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 davon können Sie die Attributknoten, Textknoten und weitere Element-Kindknoten eines Elements ansprechen.

Beispiel
<html>
<head>
  <title>Test</title>
</head>
<body>
<h1 id="Ueberschrift" class="topnews">Knoten in der <i>Baumstruktur</i></h1>

<script>
  Elementknoten = document.getElementById("Ueberschrift");
  WertErsterKindknoten = Elementknoten.firstChild.nodeValue;
  document.querySelector('output').innerText = 'Der Wert ihres ersten Kindknotens lautet: <b>' + WertErsterKindknoten + '<\/b>';
</script>
</body>
</html>

Die Beispieldatei enthält eine Überschrift erster Ordnung mit Text, von dem ein Teil wiederum als kursiv ausgezeichnet ist. In dem JavaScript, das unterhalb davon notiert ist, wird zunächst mit document.getElementById("Ueberschrift") (ohne weitere Eigenschaft oder Methode dahinter) auf das h1-Element der Überschrift zugegriffen. Der Rückgabewert von getElementById() ist das Knotenobjekt der Überschrift. Der Rückgabewert wird im Beispiel in der Variablen Elementknoten gespeichert. Diese Variable speichert also einen gültigen Knoten des Dokuments, und auf die Variable sind daher die Eigenschaften und Methoden des Node-Objekts anwendbar. Im Beispiel wird mit Elementknoten.firstChild.nodeValue der Wert des ersten Kindknotens der Überschrift ermittelt. Dessen Wert wird schließlich ins Dokument geschrieben.

Die Verwendung von Variablen ist nicht zwingend erforderlich. Das obige Beispiel funktioniert genauso, wenn Sie notieren:

document.querySelector('output').innerText = "Der Wert ihres ersten Kindknotens lautet: <b>" + document.getElementById("Ueberschrift").firstChild.nodeValue + "<\/b>";

Der geschriebene Wert lautet im Beispiel: Knoten in der ... der erste Kindknoten der Überschrift ist also ihr Zeicheninhalt. Das Wort Baumstruktur gehört nicht dazu, da es ja durch ein i-Element ausgezeichnet ist, das selbst wieder einen eigenen, weiteren Kindknoten der Überschrift darstellt.

NodeList

Eine NodeList ist eine Sammlung mehrerer Knoten des DOM. Je nach Herkunft kann eine NodeList statisch oder live sein. Eine statische NodeList ändert sich nicht mehr, auch wenn das DOM nach ihrer Ermittlung verändert wird. Im Gegensatz dazu spiegelt eine live node list jederzeit den aktuellen Stand des DOM-Teils wider, auf den den sie sich bezieht.

Beachten Sie: Auch wenn sie so aussieht, ist die NodeList kein Array.[2]

Sie können eine NodeList beispielsweise auf folgenden Wegen erhalten:

Eigenschaft:

Methoden:

Nodelist.length

Die Eigenschaft Nodelist.length liest die Anzahl der Knoten in der NodeList aus.

Nodelist.item()

Die Methode Nodelist.item() ermöglicht es, auf einen bestimmten Knoten der NodeList zuzugreifen. JavaScript unterstützt, wie bei Arrays, auch den Item-Zugriff mit eckigen Klammern.

Beispiel
nodeItem = nodeList[index];

Nodelist.forEach()

Die Methode Nodelist.forEach() funktioniert genau wie die forEach-Methode von Arrays. Sie können damit alle Elemente einer NodeList durchlaufen und für jedes Element darin eine Callback-Funktion aufrufen. Diese Callback-Funktion erhält drei Parameter: Das Element, der Index dieses Elements in der NodeList, und die NodeList selbst.

Beispiel
nodeList.forEach(element => element.textContent = '');

Quellen

  1. W3C: Interface Comment
  2. MDN: Why_is_NodeList_not_an_Array

Weblinks