Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Einführung in das DOM-Scripting

Beim Schreiben von Webseiten und Apps ist eine der häufigsten Aufgaben, die Dokumentstruktur in irgendeiner Weise zu verändern. Dies geschieht in der Regel durch Manipulation des Document Object Model (DOM) über eine Reihe von eingebauten Browser-APIs zur Steuerung von HTML- und Stil-Informationen. In diesem Artikel führen wir Sie in das DOM-Scripting ein.

Voraussetzungen: Ein Verständnis von HTML und den Grundlagen von CSS, sowie Vertrautheit mit den JavaScript-Grundlagen, die in früheren Lektionen behandelt wurden.
Lernziele:
  • Was das DOM ist — die interne Darstellung der HTML-Struktur des Dokuments als Hierarchie von Objekten im Browser.
  • Die wichtigen Teile eines Webbrowsers, wie sie in JavaScript dargestellt werden — Navigator, Window und Document.
  • Wie DOM-Knoten relativ zueinander im DOM-Baum existieren — Wurzel, Elternteil, Kind, Geschwister und Nachkommen.
  • Wie man Referenzen zu DOM-Knoten erhält, neue Knoten erstellt, Knoten und Attribute hinzufügt und entfernt.
  • Wie man CSS-Stile mit JavaScript manipuliert.

Die wichtigen Teile eines Webbrowsers

Web-Browser sind sehr komplizierte Softwarestücke mit vielen beweglichen Teilen, von denen viele nicht von einem Webentwickler mit JavaScript gesteuert oder manipuliert werden können. Sie könnten denken, dass solche Einschränkungen etwas Schlechtes sind, aber Browser sind aus guten Gründen, größtenteils aus Sicherheitsgründen, gesperrt. Stellen Sie sich vor, eine Website könnte Zugang zu Ihren gespeicherten Passwörtern oder anderen sensiblen Informationen erhalten und sich als Sie in Websites einloggen?

Trotz der Einschränkungen geben uns Web-APIs dennoch Zugriff auf viele Funktionen, die uns ermöglichen, eine Vielzahl von Dingen mit Webseiten zu tun. Es gibt einige wirklich offensichtliche Teile, auf die Sie regelmäßig in Ihrem Code zugreifen werden — betrachten Sie das folgende Diagramm, das die Hauptteile eines Browsers darstellt, die direkt in das Betrachten von Webseiten involviert sind:

Wichtige Teile des Webbrowsers; Das Dokument ist die Webseite. Das Fenster umfasst das gesamte Dokument und auch den Tab. Der Navigator ist der Browser, der das Fenster (welches das Dokument umfasst) und alle anderen Fenster enthält.

  • Das Fenster repräsentiert den Browsertab, in den eine Webseite geladen wird; Dies wird in JavaScript durch das Window-Objekt dargestellt. Mit den auf diesem Objekt verfügbaren Methoden können Sie Dinge wie die Rückgabe der Fenstergröße tun (siehe Window.innerWidth und Window.innerHeight), das in diesem Fenster geladene Dokument manipulieren, spezifische Daten zu diesem Dokument auf der Clientseite speichern (zum Beispiel mit einer lokalen Datenbank oder einem anderen Speichermedium), einen Ereignishandler an das aktuelle Fenster anhängen und mehr.
  • Der Navigator repräsentiert den Zustand und die Identität des Browsers, wie er im Web existiert. In JavaScript wird dies durch das Navigator-Objekt dargestellt. Sie können dieses Objekt verwenden, um Dinge wie die bevorzugte Sprache des Benutzers zu erhalten, einen Medienstream von der Webcam des Benutzers usw.
  • Das Dokument (im Browser durch das DOM dargestellt) ist die tatsächliche Seite, die im Fenster geladen ist, und wird in JavaScript durch das Document-Objekt dargestellt. Sie können dieses Objekt verwenden, um Informationen über das HTML und CSS, das das Dokument bildet, zurückzugeben und zu manipulieren; Beispielsweise eine Referenz auf ein Element im DOM bekommen, dessen Textinhalt ändern, neue Stile darauf anwenden, neue Elemente erstellen und diese dem aktuellen Element als Kinder hinzufügen oder sogar vollständig löschen.

In diesem Artikel konzentrieren wir uns hauptsächlich auf die Manipulation des Dokuments, aber wir zeigen einige andere nützliche Dinge nebenbei.

Das Document Object Model

Lassen Sie uns einen kurzen Rückblick auf das Document Object Model (DOM) geben, das wir bereits früher im Kurs betrachtet haben. Das in jedem Ihrer Browsertabs aktuell geladene Dokument wird durch ein DOM dargestellt. Dies ist eine "Baumstruktur"-Darstellung, die vom Browser erstellt wird und es ermöglicht, dass die HTML-Struktur leicht von Programmiersprachen aus zugänglich ist — beispielsweise verwendet der Browser es selbst, um Stile und andere Informationen auf die korrekten Elemente anzuwenden, während er eine Seite rendert, und Entwickler wie Sie können das DOM mit JavaScript nach dem Rendern der Seite manipulieren.

Hinweis: Scrimbas The Document Object Model MDN-Partner für Lernen bietet eine nützliche Einführung in den Begriff "DOM" und dessen Bedeutung.

Wir haben eine Beispielseite unter dom-example.html erstellt (siehe auch live). Versuchen Sie, dies in Ihrem Browser zu öffnen — es ist eine sehr einfache Seite mit einem <section>-Element, in dem Sie ein Bild und einen Absatz mit einem Link darin finden. Der HTML-Quellcode sieht so aus:

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Simple DOM example</title>
  </head>
  <body>
    <section>
      <img
        src="dinosaur.png"
        alt="A red Tyrannosaurus Rex: A two legged dinosaur
        standing upright like a human, with small arms, and a
        large head with lots of sharp teeth." />
      <p>
        Here we will add a link to the
        <a href="https://www.mozilla.org/">Mozilla homepage</a>
      </p>
    </section>
  </body>
</html>

Das DOM hingegen sieht so aus:

Baumstruktur-Darstellung des Document Object Model: Der oberste Knoten ist der Doctype und das HTML-Element. Kindknoten des HTML enthalten head und body. Jedes Kindelement ist ein Zweig. Auch aller Text, sogar Leerzeichen, wird angezeigt.

Hinweis: Dieses DOM-Baumdiagramm wurde mit Ian Hicksons Live DOM viewer erstellt.

Jeder Eintrag im Baum wird als Knoten bezeichnet. Sie können auf dem obigen Diagramm sehen, dass einige Knoten Elemente darstellen (erkennbar als HTML, HEAD, META usw.) und andere Text (als #text erkennbar). Es gibt auch andere Arten von Knoten, aber dies sind die Haupttypen, denen Sie begegnen werden.

Knoten werden auch nach ihrer Position im Baum relativ zu anderen Knoten bezeichnet:

  • Wurzelknoten: Der oberste Knoten im Baum, der im Fall von HTML immer der HTML-Knoten ist (andere Markup-Vokabulare wie SVG und benutzerdefiniertes XML haben unterschiedliche Wurzelelemente).
  • Kindknoten: Ein Knoten direkt innerhalb eines anderen Knotens. Zum Beispiel ist IMG ein Kind von SECTION im obigen Beispiel.
  • Nachkommensknoten: Ein Knoten irgendwo innerhalb eines anderen Knotens. Zum Beispiel ist IMG ein Kind von SECTION im obigen Beispiel und ist auch ein Nachkomme. IMG ist kein Kind von BODY, da es zwei Ebenen darunter im Baum liegt, aber es ist ein Nachkomme von BODY.
  • Elternknoten: Ein Knoten, der einen anderen Knoten innerhalb hat. Zum Beispiel ist BODY der Elternknoten von SECTION im obigen Beispiel.
  • Geschwisterknoten: Knoten, die sich auf derselben Ebene unter demselben Elternknoten im DOM-Baum befinden. Zum Beispiel sind IMG und P Geschwister im obigen Beispiel.

Es ist nützlich, sich mit dieser Terminologie vertraut zu machen, bevor Sie mit dem DOM arbeiten, da viele der Ihnen begegneten Codebegriffe diese verwenden. Diese werden Ihnen auch in CSS begegnen (z. B. Nachkommenselektor, Kindselektor).

Einfache DOM-Manipulation durchführen

Um mit der DOM-Manipulation zu beginnen, starten wir mit einem praktischen Beispiel.

  1. Erstellen Sie eine lokale Kopie der dom-example.html-Seite und des dazugehörigen Bildes.

  2. Fügen Sie ein <script></script>-Element direkt über dem schließenden </body>-Tag ein.

  3. Um ein Element im DOM zu manipulieren, müssen Sie es zuerst auswählen und eine Referenz darauf in einer Variablen speichern. Fügen Sie in Ihrem Skriptelement die folgende Zeile hinzu:

    js
    const link = document.querySelector("a");
    
  4. Da wir nun die Elementreferenz in einer Variablen gespeichert haben, können wir beginnen, sie mithilfe von Eigenschaften und Methoden zu manipulieren, die dafür verfügbar sind (diese sind in Schnittstellen wie HTMLAnchorElement im Fall von <a>-Elementen, ihrer allgemeineren Elternschnittstelle HTMLElement und Node definiert — die alle Knoten in einem DOM repräsentiert). Lassen Sie uns zuerst den Text innerhalb des Links ändern, indem wir den Wert der Eigenschaft Node.textContent aktualisieren. Fügen Sie die folgende Zeile unter die vorherige hinzu:

    js
    link.textContent = "Mozilla Developer Network";
    
  5. Wir sollten auch die URL ändern, auf die der Link zeigt, damit er beim Klicken nicht an den falschen Ort führt. Fügen Sie die folgende Zeile erneut am unteren Ende hinzu:

    js
    link.href = "https://developer.mozilla.org";
    

Beachten Sie, dass es, wie bei vielen Dingen in JavaScript, viele Möglichkeiten gibt, ein Element auszuwählen und eine Referenz darauf in einer Variablen zu speichern. Document.querySelector() ist der empfohlene moderne Ansatz. Es ist praktisch, weil es Ihnen ermöglicht, Elemente mithilfe von CSS-Selektoren auszuwählen. Der obige querySelector()-Aufruf wird das erste <a>-Element auswählen, das im Dokument erscheint. Wenn Sie mehrere Elemente auswählen und etwas mit ihnen tun wollten, könnten Sie Document.querySelectorAll() verwenden, das jedes Element im Dokument auswählt, das dem Selektor entspricht, und Referenzen darauf in einem array-ähnlichen Objekt namens NodeList speichert.

Es gibt ältere Methoden zum Greifen von Elementreferenzen, wie:

  • Document.getElementById(), das ein Element mit einem gegebenen id-Attributwert auswählt, z. B. <p id="myId">Mein Paragraf</p>. Die ID wird an die Funktion als Parameter übergeben, z. B. const elementRef = document.getElementById('myId').
  • Document.getElementsByTagName(), das ein array-ähnliches Objekt zurückgibt, das alle Elemente auf der Seite eines bestimmten Typs enthält, zum Beispiel <p>s, <a>s, etc. Der Elementtyp wird an die Funktion als Parameter übergeben, z. B. const elementRefArray = document.getElementsByTagName('p').

Diese beiden funktionieren besser in älteren Browsern als die modernen Methoden wie querySelector(), sind jedoch nicht so praktisch. Schauen Sie sich um und sehen Sie, was Sie noch finden können!

Erstellen und Platzieren neuer Knoten

Das obige hat Ihnen einen kleinen Vorgeschmack auf das gegeben, was Sie tun können, aber lassen Sie uns weitergehen und uns ansehen, wie wir neue Elemente erstellen können.

  1. Gehen Sie zurück zu unserem aktuellen Beispiel und beginnen Sie damit, eine Referenz auf unser <section>-Element zu bekommen — fügen Sie den folgenden Code am Ende Ihres existierenden Scripts hinzu (tun Sie das Gleiche auch mit den anderen Zeilen):

    js
    const sect = document.querySelector("section");
    
  2. Erstellen wir nun einen neuen Absatz mithilfe von Document.createElement() und geben ihm etwas Textinhalt auf die gleiche Weise wie zuvor:

    js
    const para = document.createElement("p");
    para.textContent = "We hope you enjoyed the ride.";
    
  3. Sie können den neuen Absatz jetzt am Ende des Bereichs mithilfe von Node.appendChild() anhängen:

    js
    sect.appendChild(para);
    
  4. Schließlich fügen wir einen Textknoten zum Absatz hinzu, in dem sich der Link befindet, um den Satz schön abzuschließen. Erst erstellen wir den Textknoten mit Document.createTextNode():

    js
    const text = document.createTextNode(
      " — the premier source for web development knowledge.",
    );
    
  5. Danach holen wir uns eine Referenz auf den Absatz, in dem sich der Link befindet, und fügen den Textknoten hinzu:

    js
    const linkPara = document.querySelector("p");
    linkPara.appendChild(text);
    

Das ist das meiste, was Sie brauchen, um Knoten zum DOM hinzuzufügen — Sie werden diese Methoden viel verwenden, wenn Sie dynamische Schnittstellen erstellen (wir werden später einige Beispiele betrachten).

Verschieben und Entfernen von Elementen

Es kann vorkommen, dass Sie Knoten verschieben oder vollständig aus dem DOM löschen möchten. Dies ist durchaus möglich.

Wenn wir den Absatz mit dem darin befindlichen Link an das Ende des Bereichs verschieben wollten, könnten wir dies tun:

js
sect.appendChild(linkPara);

Dies verschiebt den Absatz nach unten ans Ende des Bereichs. Sie könnten gedacht haben, dass es eine zweite Kopie davon erstellt, aber das ist nicht der Fall — linkPara ist eine Referenz auf die einzige Kopie dieses Absatzes. Wenn Sie eine Kopie erstellen und diese auch hinzufügen wollten, müssten Sie stattdessen Node.cloneNode() verwenden.

Das Entfernen eines Knotens ist ebenfalls ziemlich einfach, zumindest wenn Sie eine Referenz auf den zu entfernenden Knoten und dessen Eltern haben. In unserem aktuellen Fall verwenden wir einfach Node.removeChild(), wie folgt:

js
sect.removeChild(linkPara);

Wenn Sie einen Knoten entfernen möchten, basierend nur auf einer Referenz auf sich selbst, was ziemlich häufig vorkommt, können Sie Element.remove() verwenden:

js
linkPara.remove();

Diese Methode wird in älteren Browsern nicht unterstützt. Sie haben keine Methode, um einem Knoten zu sagen, sich selbst zu entfernen, daher müssten Sie Folgendes tun:

js
linkPara.parentNode.removeChild(linkPara);

Versuchen Sie, die obigen Zeilen zu Ihrem Code hinzuzufügen.

Manipulation von Stilen

Es ist möglich, CSS-Stile auf verschiedene Weise über JavaScript zu manipulieren.

Zuerst können Sie eine Liste aller Stylesheets erhalten, die mit einem Dokument verbunden sind, indem Sie Document.styleSheets verwenden, das ein array-ähnliches Objekt mit CSSStyleSheet-Objekten zurückgibt. Sie können dann nach Belieben Stile hinzufügen/entfernen. Wir werden jedoch nicht auf diese Funktionen eingehen, da sie eine etwas archaische und schwierige Methode zur Manipulation von Stilen darstellen. Es gibt viel einfachere Wege.

Der erste Weg ist das Hinzufügen von Inline-Stilen direkt auf die Elemente, die Sie dynamisch stylen möchten. Dies geschieht mit der HTMLElement.style-Eigenschaft, die Inline-Stilinformationen für jedes Element im Dokument enthält. Sie können Eigenschaften dieses Objekts setzen, um Stile direkt zu aktualisieren.

  1. Fügen Sie als Beispiel diese Zeilen zu unserem laufenden Beispiel hinzu:

    js
    para.style.color = "white";
    para.style.backgroundColor = "black";
    para.style.padding = "10px";
    para.style.width = "250px";
    para.style.textAlign = "center";
    
  2. Laden Sie die Seite neu und Sie werden sehen, dass die Stile auf den Absatz angewendet wurden. Wenn Sie sich diesen Absatz im Page Inspector/DOM Inspector Ihres Browsers ansehen, werden Sie sehen, dass diese Zeilen tatsächlich Inline-Stile zum Dokument hinzufügen:

    html
    <p
      style="color: white; background-color: black; padding: 10px; width: 250px; text-align: center;">
      We hope you enjoyed the ride.
    </p>
    

Hinweis: Beachten Sie, wie die JavaScript-Versionen der CSS-Stile in lower camel case geschrieben sind, während die CSS-Versionen mit Bindestrichen versehen sind (kebab-case) (z. B. backgroundColor versus background-color). Stellen Sie sicher, dass Sie diese nicht verwechseln, da es sonst nicht funktioniert.

Es gibt eine weitere gängige Methode, um Stile auf Ihrem Dokument dynamisch zu manipulieren, nämlich die Stile in einem separaten Stylesheet zu schreiben und diese Stile zu referenzieren, indem Sie einen Klassennamen hinzufügen/entfernen.

  1. Löschen Sie die vorherigen fünf Zeilen, die Sie dem JavaScript hinzugefügt haben.

  2. Fügen Sie das Folgende in Ihr HTML-<head>-Element ein:

    html
    <style>
      .highlight {
        color: white;
        background-color: black;
        padding: 10px;
        width: 250px;
        text-align: center;
      }
    </style>
    
  3. Um diesen Klassennamen zu Ihrem Element hinzuzufügen, verwenden Sie die add()-Methode des classList des Elements:

    js
    para.classList.add("highlight");
    
  4. Laden Sie Ihre Seite neu, und Sie werden keinen Unterschied sehen — der CSS ist weiterhin auf den Absatz angewendet, aber diesmal indem er ihm eine Klasse gibt, die von unserer CSS-Regel ausgewählt wird, nicht als Inline-CSS-Stile.

Welche Methode Sie wählen, bleibt Ihnen überlassen; beide haben ihre Vor- und Nachteile. Die erste Methode benötigt weniger Setup und ist für einfache Anwendungen geeignet, während die zweite Methode puristischer ist (kein Mischen von CSS und JavaScript, keine Inline-Stile, die als schlechte Praxis gelten). Wenn Sie beginnen, größere und komplexere Apps zu erstellen, werden Sie wahrscheinlich die zweite Methode mehr verwenden, aber letztendlich liegt es an Ihnen.

An diesem Punkt haben wir noch nichts wirklich Nützliches getan! Es gibt keinen Grund, JavaScript zu verwenden, um statischen Inhalt zu erstellen — Sie könnten ihn genauso gut in Ihrem HTML schreiben und kein JavaScript verwenden. Es ist komplexer als HTML, und das Erstellen Ihres Inhalts mit JavaScript bringt auch andere

Probleme mit sich (z.B. wird es möglicherweise nicht von Suchmaschinen gelesen).

Im nächsten Abschnitt werden wir uns einen praktischeren Einsatz von DOM-APIs ansehen.

Hinweis: Sie finden unsere fertige Version des dom-example.html-Demos auf GitHub (siehe auch live).

Erstellen einer dynamischen Einkaufsliste

In dieser Übung möchten wir, dass Sie eine dynamische Einkaufsliste erstellen, die es Ihnen ermöglicht, Elemente mithilfe eines Formulareingabe und eines Buttons hinzuzufügen. Wenn Sie ein Element hinzufügen und den Button drücken:

  • Sollte das Element in der Liste erscheinen.
  • Jedes Element sollte einen Button erhalten, der gedrückt werden kann, um dieses Element von der Liste zu löschen.
  • Die Eingabe sollte geleert und fokussiert werden, damit Sie ein weiteres Element eingeben können.

Das fertige Demo sieht ungefähr wie folgt aus — probieren Sie es aus, bevor Sie es erstellen!

Um die Übung abzuschließen, folgen Sie den untenstehenden Schritten und stellen Sie sicher, dass sich die Liste wie beschrieben verhält.

  1. Laden Sie zunächst eine Kopie unserer shopping-list.html-Startdatei herunter und erstellen Sie eine Kopie davon. Sie werden sehen, dass sie einige minimale CSS-Stile enthält, sowie ein div mit einem Label, Eingabe und Button und eine leere Liste und <script>-Element. Sie werden alle Ihre Ergänzungen im Skript vornehmen.
  2. Erstellen Sie drei Variablen, die Referenzen auf die Liste (<ul>), <input> und <button>-Elemente enthalten.
  3. Erstellen Sie eine Funktion, die ausgeführt wird, wenn der Button geklickt wird.
  4. Speichern Sie im Funktionskörper zunächst den aktuellen Wert des Eingabeelements in einer Variablen.
  5. Leeren Sie anschließend das Eingabeelement, indem Sie dessen Wert auf einen leeren String setzen — "".
  6. Erstellen Sie drei neue Elemente — ein Listenelement (<li>), <span> und <button> — und speichern Sie diese in Variablen.
  7. Fügen Sie das span- und das Button-Element als Kinder des Listenelements hinzu.
  8. Setzen Sie den Textinhalt des span-Elements auf den zuvor gespeicherten Wert des Eingabeelements und den Textinhalt des Button-Elements auf 'Löschen'.
  9. Fügen Sie das Listenelement als Kind der Liste hinzu.
  10. Hängen Sie einen Ereignishandler an den Lösch-Button an, sodass beim Klicken das gesamte Listenelement (<li>...</li>) gelöscht wird.
  11. Verwenden Sie schließlich die focus()-Methode, um das Eingabeelement zu fokussieren, bereit für die Eingabe des nächsten Einkaufslistelements.

Zusammenfassung

Wir sind am Ende unseres Studiums der Dokument- und DOM-Manipulation angelangt. An diesem Punkt sollten Sie verstehen, was die wichtigen Teile eines Webbrowsers im Hinblick auf die Steuerung von Dokumenten und andere Aspekte der Web-Erfahrung des Benutzers sind. Am wichtigsten ist, dass Sie verstehen, was das Document Object Model ist und wie man es manipuliert, um nützliche Funktionen zu erstellen.

Siehe auch