Das Document Object Model

Verändere eine geöffnete Webseite mit JavaScript. Lerne, wie der Browser HTML in einen Baum aus Objekten umwandelt, wähle die benötigten Elemente aus und ändere ihre Texte, Attribute, Klassen und Stile. Erstelle, verschiebe und entferne Elemente und wandle Datenarrays in Listen und Tabellen um, die mit den Daten Schritt halten, ohne die Seite neu zu laden.

AnfängerEinheit 5 von 9 in Kurs: JavaScript – DOM, Ereignisse und asynchroner Code

Was du lernst

  1. Erkläre, was das Document Object Model ist, wie der Browser es aus HTML aufbaut und wie seine Knoten zusammenhängen, damit du dich auf jeder Seite zurechtfindest.
    • Beschreibe das DOM als Baum aus Knoten
      Erkläre, was das DOM ist, wie der Browser es aus HTML aufbaut, welche Arten von Knoten es enthält und wie es sich vom HTML-Quelltext unterscheidet.
    • Navigiere von einem Element zu seinem Elternelement, seinen Kindelementen und seinen Geschwisterelementen
      Navigiere von einem beliebigen Element durch den Baum zu seinen verwandten Knoten, wähle zwischen Eigenschaften mit Textknoten und solchen, die nur Elemente zurückgeben, und finde den nächsten passenden Vorfahrenknoten.
  2. Finde mit CSS-Selektoren genau die Elemente, die ein Skript benötigt, behandle fehlende Elemente und arbeite mit Sammlungen passender Elemente.
    • Wähle ein einzelnes Element aus
      Finde ein Element mit querySelector oder getElementById, suche innerhalb eines Teils der Seite und behandle den Fall, dass nichts passt.
    • Wähle mehrere Elemente aus und arbeite mit den Ergebnissen
      Wähle alle passenden Elemente aus, durchlaufe die Ergebnisse, wandle sie bei Bedarf in ein Array um und erkenne, wann eine Sammlung sich selbst aktualisiert.
  3. Aktualisiere die Texte von Elementen und die Attribute und Eigenschaften, die sie steuern. Wähle eine sichere Methode für Inhalte von Nutzern oder aus Daten und speichere zusätzliche Daten an Elementen.
    • Ändere Text und HTML innerhalb eines Elements
      Lies und ersetze den Inhalt eines Elements mit textContent, innerText und innerHTML und schütze Seiten vor eingeschleustem Code.
    • Lies und setze Attribute und Eigenschaften
      Arbeite mit Attributen über getAttribute und setAttribute sowie mit den zugehörigen Elementeigenschaften und behandle boolesche Attribute und Unterschiede zwischen Attributen und Eigenschaften.
    • Speichere Daten an Elementen und lies Formularfelder aus
      Speichere zusätzliche Informationen mit Datenattributen an Elementen und lies und setze den aktuellen Wert von Formularfeldern.
  4. Schalte CSS-Klassen um, setze Inline-Stile für berechnete Werte, lies die vom Browser angewandten Stile und blende Teile einer Seite ein oder aus.
    • Füge CSS-Klassen hinzu, entferne sie und schalte sie um
      Ändere das Aussehen eines Elements, indem du Klassen mit classList umschaltest und die visuellen Regeln im Stylesheet belässt.
    • Setze Inline-Stile und lies berechnete Stile aus
      Setze Inline-Stile über die Eigenschaft style, wenn ein Wert zur Laufzeit berechnet wird, entferne sie wieder und lies die Stile, die der Browser tatsächlich anwendet.
    • Blende Teile einer Seite ein und aus
      Blende Elemente mit dem Attribut hidden oder einer Klasse aus und wieder ein, wähle zwischen den CSS-Möglichkeiten zum Unsichtbarmachen und halte den Zustand für Screenreader-Nutzer eindeutig.
  5. Erstelle neue Elemente in JavaScript, platziere sie genau an der richtigen Stelle und entferne, ersetze oder kopiere Elemente, damit sich die Seite ohne Neuladen ändert.
    • Erstelle neue Elemente und füge sie ein
      Erstelle Elemente mit createElement, fülle sie mit Text und Attributen und füge sie am Ende, am Anfang oder neben einem anderen Element ein.
    • Entferne, ersetze und kopiere Elemente
      Entferne Elemente von der Seite, leere einen Container, ersetze ein Element durch ein anderes und erstelle Kopien mit cloneNode.
  6. Wandle Datenarrays in Listen und Tabellen auf der Seite um, erstelle viele Einträge effizient und halte die Seite bei Änderungen mit den Daten aktuell.
    • Erstelle Listeneinträge und Tabellenzeilen aus einem Array
      Wandle ein Array aus Objekten mit textContent in Listeneinträge oder Tabellenzeilen um, zeige sinnvolle Ausgaben für leere Listen und fehlende Werte an und verknüpfe jedes Element mit seinen Daten.
    • Erstelle viele Elemente effizient mit Dokumentfragmenten und template-Elementen
      Füge viele neue Elemente mit einem DocumentFragment oder einem einzelnen append in einem Schritt ein und verwende Markup aus einem HTML-template-Element wieder.
    • Aktualisiere die Seite, wenn sich die Daten ändern
      Halte die Daten als einzige Source of Truth, rendere nach jeder Änderung erneut daraus und zeige gefilterte, sortierte und zusammengefasste Ansichten an, ohne die ursprünglichen Daten zu verlieren.

Document Object Model einfach erklärt

6 Kapitel

1

Lies die Seite als Baum

Der Browser wandelt HTML in Objekte um, die JavaScript lesen und ändern kann. Diese Objekte bilden einen Baum. Um ein Seitenelement zu finden, musst du deshalb auch verstehen, wo es sich zwischen den anderen Knoten befindet. Beginne damit, vertraute Tags mit den Objekten im Browser zu verbinden. Verfolge dann die Beziehungen zwischen Eltern-, Kind- und Geschwisterknoten und achte auf die Textknoten, die aus Leerzeichen und Zeilenumbrüchen entstehen. Mit den DevTools kannst du diesen Baum sehen, während dein Code ihn verändert.

1.1 HTML wird zu einem Baum aus Objekten

Das Document Object Model, kurz DOM, ist der dynamische Baum aus Seitenobjekten im Browser. JavaScript liest und ändert diese Objekte, um die Seite ohne Neuladen zu aktualisieren. Der Browser stellt die DOM-API bereit; JavaScript ist die Sprache, mit der sie aufgerufen wird.

Beginne beim Dokument

document ist der Einstiegspunkt. document.documentElement verweist auf <html>, document.head auf <head> und document.body auf <body>. Der Browser-Tab wird durch window repräsentiert, dessen Eigenschaft document auf dieses Dokument verweist.

Jeder Eintrag im Baum ist ein Knoten. Elemente stehen für Tags; Textknoten enthalten Zeichen; Kommentarknoten enthalten HTML-Kommentare; der Dokumentknoten steht über den Elementen der Seite. Ihre nodeType-Werte sind entsprechend 1, 3, 8 und 9. Jedes Element ist ein Knoten, aber Text und Kommentare sind keine Elemente.

Lies die Familienbeziehungen
<ul id="menu"><li>Home</li><li>About</li></ul>

Die Liste ist der Elternknoten zweier Eintragselemente, die Geschwisterknoten sind. Jeder Eintrag ist ihr Kindknoten. Der erste Eintrag hat einen Textknoten als Kindknoten, der „Home“ enthält. Die Liste ist ein Vorfahrenknoten dieses Textknotens und der Text ein Nachfahrenknoten der Liste. Diese Beziehungen beschreiben die Verschachtelung, nicht die Positionen auf dem Bildschirm.

Leerzeichen und Zeilenumbrüche zwischen Tags werden normalerweise zu Textknoten mit Leerraumzeichen. Eine eingerückte Liste kann deshalb zwei Kindelemente, aber mehr als zwei Kindknoten haben. children und firstElementChild geben nur Elemente zurück; childNodes und firstChild schließen Text und Kommentare ein.

Vergleiche den Baum mit dem Quelltext

Beim Parsen wird Markup in den Baum umgewandelt und kann dabei ergänzt oder korrigiert werden. Zeilen, die direkt innerhalb einer <table> stehen, erhalten einen <tbody>-Elternknoten. Fehlende <html>-, <head>- oder <body>-Elemente können ebenfalls ergänzt werden. Wähle aus dem tatsächlichen Baum aus, einschließlich dieser vom Parser hinzugefügten Elemente.

Änderungen durch Skripte betreffen das aktuelle DOM des Browsers, nicht die HTML-Datei auf dem Server. „Seitenquelltext anzeigen“ zeigt das ursprüngliche HTML, während der Bereich „Elemente“ der DevTools den aktuellen Baum zeigt. Beim Neuladen wird das DOM neu aufgebaut; eine Änderung allein speichert die zugrunde liegenden Daten nicht.

Untersuche ein Objekt

Klicke mit der rechten Maustaste auf ein Element und wähle „Untersuchen“. Gib $0 in der Konsole ein, um auf das ausgewählte Element zu verweisen. console.log($0) stellt es als Markup dar; console.dir($0) zeigt seine Eigenschaften. Klappe eine eingerückte Liste auf, um die Leerraumknoten neben ihren Eintragselementen zu sehen.

Wichtige Erkenntnisse

  • Das DOM ist ein vom Browser bereitgestellter Baum, den JavaScript lesen und ändern kann.
  • Elemente, Text, Kommentare und das Dokument sind verschiedene Arten von Knoten.
  • Leerraumzeichen und vom Parser hinzugefügte Elemente können dazu führen, dass sich das DOM vom geschriebenen HTML unterscheidet.
  • Untersuche den aktuellen Baum in den DevTools; eine DOM-Änderung schreibt das HTML auf dem Server nicht um.

1.2 Verfolge Eltern-, Kind- und Geschwisterknoten

Über Baumeigenschaften kann ein Skript von einem bereits vorliegenden Element aus benachbarte Inhalte erreichen. Entscheide, ob dieser Pfad Text und Kommentare oder nur Elemente einschließen soll.

Wähle Knoten oder Elemente

Zu den Knoteneigenschaften gehören parentNode, childNodes, firstChild, lastChild, previousSibling und nextSibling. Ihre Gegenstücke für Elemente sind parentElement, children, firstElementChild, lastElementChild, previousElementSibling und nextElementSibling. children ist eine HTMLCollection; childNodes ist eine NodeList.

<ul id="tasks">
  <li>Buy milk</li>
  <li>Call Sam</li>
</ul>

Hier ist tasks.childNodes.length gleich 5: zwei Elemente und drei Folgen von Leerraumzeichen. tasks.children.length ist gleich 2. tasks.firstChild ist ein Textknoten mit Leerraumzeichen, während tasks.firstElementChild.textContent gleich „Buy milk“ ist. Indizes beginnen bei 0, daher ist tasks.children[1] der zweite Eintrag.

Folge einem kurzen Pfad
const tasks = document.querySelector("#tasks");
const first = tasks.firstElementChild;
const second = first.nextElementSibling;
console.log(second.textContent);
console.log(second.parentElement === tasks);

Die Ausgabe ist „Call Sam“, gefolgt von true. tasks.lastElementChild erreicht denselben Eintrag direkt, ebenso wie tasks.children[tasks.children.length - 1].

Behandle einen fehlenden verwandten Knoten

Das nextElementSibling des letzten Eintrags ist null. Ein Element ohne Kindelemente hat firstElementChild === null und eine leere children-Sammlung. Der parentNode des HTML-Wurzelelements ist das Dokument, sein parentElement ist aber null.

Das Lesen einer Eigenschaft von null löst einen TypeError aus. Prüfe zuerst oder verwende second.nextElementSibling?.textContent, was undefined ergibt, wenn kein nächstes Element existiert.

Finde einen umschließenden Eintrag

closest(selector) prüft das aktuelle Element und dann seine Vorfahrenknoten und gibt den nächsten Treffer oder null zurück. Eine Schaltfläche innerhalb von <li class="task" data-id="7"> kann button.closest(".task") verwenden; die dataset.id des gefundenen Eintrags ist „7“. matches(selector) prüft dagegen nur das aktuelle Element und gibt einen booleschen Wert zurück.

Lange Pfade wie el.parentElement.parentElement.nextElementSibling hängen von der genauen Verschachtelung ab. Ein zusätzliches umschließendes Element ändert ihre Bedeutung. Verwende Selektoren für benannte Bereiche, kurze Navigation für stabile Beziehungen und closest() für einen umschließenden Eintrag.

Wichtige Erkenntnisse

  • Verwende die Navigation nur über Elemente, wenn Leerraumzeichen und Kommentare übersprungen werden sollen.
  • Sammlungen beginnen bei Index 0; ihre Länge ist eine Anzahl, nicht der letzte Index.
  • Ein fehlender verwandter Knoten ist null; prüfe ihn, bevor du daraus liest.
  • closest() prüft das Element selbst und danach seine Vorfahrenknoten.
  • matches() prüft das aktuelle Element, ohne durch den Baum zu navigieren.
2

Finde Seitenelemente

Eine DOM-Änderung beginnt mit einer Referenz auf das richtige Element. Mit CSS-Selektoren kannst du die ganze Seite oder nur einen Container durchsuchen, während du mit Sammlungsmethoden viele Ergebnisse verarbeiten kannst. Der Rückgabewert ist wichtig: Eine Suche kann ein Element oder null liefern, eine andere gibt immer eine Sammlung zurück. Du musst auch wissen, wann das Skript ausgeführt wird und ob sich eine gespeicherte Sammlung bei Änderungen der Seite verändert, denn beides beeinflusst, was dein Code findet.

2.1 Finde ein Element und prüfe das Ergebnis

Ein Selektor macht aus einer Beschreibung eines Elements eine Objektreferenz. Beginne mit der kleinsten Suche, die das benötigte Element identifiziert, und prüfe dann, ob es gefunden wurde, bevor du es änderst.

Suche mit einem CSS-Selektor oder einer ID

document.querySelector(selector) gibt das erste passende Element in Dokumentreihenfolge zurück. Die Methode akzeptiert vertraute CSS-Selektoren: "h1", ".price", "#cart", "nav a" oder 'input[type="email"]'. Wenn nichts passt, gibt sie null zurück.

document.getElementById("cart") sucht direkt nach einer ID. Das Argument ist die ID ohne Zusatz. getElementById("#cart") sucht nach einer ID, die tatsächlich das Rautezeichen enthält, während querySelector("cart") nach einem <cart>-Tag sucht. Verwende querySelector("#cart") für den ID-Selektor.

IDs müssen eindeutig sein. Wenn kopiertes Markup zwei Elementen dieselbe ID gibt, liefern diese Suchen das erste in Dokumentreihenfolge zurück. Korrigiere das doppelte Markup, statt zu erwarten, dass eine ID-Suche die zweite Kopie erreicht.

Suche innerhalb eines Containers

Angenommen, mehrere Karten haben ein Element mit der Klasse name. Wähle zuerst die Profilkarte aus und durchsuche dann ihre Nachfahrenelemente:

const card = document.querySelector("#profile");
if (card) {
  const name = card.querySelector(".name");
  if (name) name.textContent = "Maya";
}

Die innere Suche ist auf die Profilkarte beschränkt, sodass ein früheres .name an anderer Stelle nicht stört. Der Container selbst kommt bei seiner eigenen querySelector()-Suche nicht als Treffer infrage. Gewöhnliche Elemente unterstützen diese Methode, aber getElementById() gehört zu document.

Unterscheide einen fehlenden Treffer von einem ungültigen Selektor

Eine gültige Suche ohne Treffer ergibt null. Der Versuch, null.textContent zu setzen, löst einen TypeError aus. Sichere daher optionale Inhalte ab:

const banner = document.querySelector(".banner");
if (banner) banner.textContent = "Sale ends Friday";

Ein ungültiger CSS-Selektor löst einen SyntaxError aus, bevor es ein Ergebnis geben kann. Für <p id="1st"> ist querySelector("#1st") ungültig, weil die Ziffer in diesem CSS-ID-Selektor maskiert werden muss. getElementById("1st") verwendet eine ID als Literal und funktioniert direkt.

Führe den Code aus, nachdem das benötigte Markup existiert

Ein klassisches externes Skript im <head> wird ausgeführt, bevor der Browser den Body geparst hat. Eine Suche nach einem späteren Absatz gibt daher null zurück, selbst wenn das HTML ihn enthält. Verwende <script src="app.js" defer></script> für die Ausführung nach dem Parsen, verwende ein Modulskript oder platziere das Skript direkt vor </body>. Modulskripte werden standardmäßig verzögert ausgeführt. Das Attribut defer hat auf ein klassisches Inline-Skript keine Wirkung.

Bei einer HTML-Seite, die mit <!DOCTYPE html> beginnt, wird bei ID- und Klassenselektoren zwischen Groß- und Kleinschreibung unterschieden: .Price passt nicht zu class="price". Bei HTML-Tag-Selektoren wird nicht unterschieden, sodass "LI" und "li" beide zu Listeneinträgen passen. Wenn eine Suche fehlschlägt, prüfe Schreibweise, Selektorsyntax, Suchcontainer und Ausführungszeitpunkt des Skripts.

Wichtige Erkenntnisse

  • querySelector() gibt den ersten Treffer oder null zurück.
  • getElementById() erwartet eine ID ohne Zusatz; querySelector() erwartet CSS-Selektorsyntax.
  • Durchsuche die Nachfahrenelemente eines Containers, wenn eine Klasse in mehreren Seitenbereichen vorkommt.
  • Ein fehlender Treffer ergibt null; ungültige Selektorsyntax löst einen Fehler aus.
  • Führe DOM-Code aus, nachdem sein Markup geparst wurde.
  • Halte IDs eindeutig und achte bei ID- und Klassenselektoren auf Groß- und Kleinschreibung.

2.2 Arbeite mit Sammlungen passender Elemente

Verwende querySelectorAll(), wenn dieselbe Operation auf mehrere Elemente angewendet werden soll. Das Ergebnis ist eine Sammlung. Du musst also entscheiden, wie du sie durchläufst und ob du eine Momentaufnahme oder eine dynamische Ansicht benötigst.

Lies und durchlaufe eine NodeList

document.querySelectorAll(".note") gibt eine NodeList passender Elemente in Dokumentreihenfolge zurück. Ohne Treffer erhältst du eine leere NodeList mit der Länge 0. Die Sammlung selbst ist dennoch ein Truthy-Wert; if (notes) sagt dir nicht, ob sie Elemente enthält. Prüfe notes.length.

Eine NodeList unterstützt Indizes, length, forEach() und for...of, ist aber kein Array und hat kein map(), filter() oder reduce(). Wandle sie um, wenn du diese Methoden benötigst:

const weights = Array.from(document.querySelectorAll(".weight"))
  .map(el => Number(el.textContent));
const total = weights.reduce((sum, weight) => sum + weight, 0);

Für Elemente mit „4.5“, „12“ und „3.25“ ist das Array [4.5, 12, 3.25] und die Summe beträgt 19,75 kg. Die Umwandlung in Zahlen ist wichtig, weil die Textwerte Zeichenketten sind.

Eine Sammlung ist kein zusammengefasstes Element. Das Setzen von notes.textContent ändert keine Notiz, und notes.classList.add("saved") löst einen Fehler aus, weil die NodeList keine classList hat. Wende die Änderung auf jedes Element an:

const notes = document.querySelectorAll(".note");
notes.forEach(note => note.classList.add("saved"));
Vergleiche statische und dynamische Ergebnisse

Die NodeList von querySelectorAll() ist statisch: Ihre Zugehörigkeit steht zum Zeitpunkt der Suche fest. Die Elemente, auf die sie verweist, sind weiterhin die tatsächlichen Objekte, sodass sich ihr Text oder ihre Klassen ändern können.

getElementsByClassName("note") und getElementsByTagName("li") geben eine dynamische HTMLCollection zurück. Auch children ist dynamisch. Diese Sammlungen aktualisieren ihre Zugehörigkeit, wenn sich das DOM ändert. Sie unterstützen Indizes und for...of, aber kein forEach().

Speichere in einer Liste mit drei .item-Elementen sowohl list.getElementsByClassName("item") als auch list.querySelectorAll(".item"). Hänge ein viertes passendes Element an. Die dynamische Sammlung hat nun die Länge 4; die Momentaufnahme hat weiterhin die Länge 3.

Vermeide die Falle einer schrumpfenden dynamischen Sammlung

Angenommen, vier Elemente gehören zu einer dynamischen Sammlung namens live:

for (let i = 0; i < live.length; i++) {
  live[i].classList.remove("item");
}

Das Entfernen der ersten Klasse entfernt dieses Element aus der Sammlung. Das nächste Element rückt auf Index 0, aber die Schleife geht zu Index 1 weiter und überspringt es. Nur zwei der vier verlieren die Klasse. Durchlaufe Array.from(live) oder eine Momentaufnahme von querySelectorAll(), wenn sich die Zugehörigkeit ändert.

Prüfe Leerzeichen in Selektoren

.task.done bedeutet ein Element mit beiden Klassen. .task .done bedeutet ein .done-Nachfahrenelement innerhalb eines .task. Zähle bei <li class="task done"> erledigte Einträge mit document.querySelectorAll(".task.done").length. Ein Komma kombiniert Selektoren: "h2, h3" gibt Treffer in Dokumentreihenfolge zurück, nicht erst alle Überschriften eines Typs und dann die des anderen.

Wichtige Erkenntnisse

  • Durchlaufe die Mitglieder einer Sammlung, um ihre Inhalte oder Klassen zu ändern.
  • querySelectorAll() gibt eine statische NodeList zurück; ein leeres Ergebnis hat die Länge 0.
  • Wandle Sammlungen mit Array.from() oder Spread um, bevor du Methoden verwendest, die nur Arrays haben.
  • Bei dynamischen Sammlungen ändert sich die Zugehörigkeit, wenn sich passende Elemente ändern.
  • Erstelle eine Momentaufnahme vor einer Schleife, die Mitglieder einer dynamischen Sammlung entfernt.
  • Ein Leerzeichen in einem Selektor ändert die gesuchte Beziehung.
3

Aktualisiere Inhalte und Elementdaten

Ein Element enthält verschiedene Arten von Informationen: sichtbaren Text, HTML-Struktur, Attribute und JavaScript-Eigenschaften. Wenn du die richtige Art wählst, kannst du eine Beschriftung aktualisieren, einen Link ändern, ein Feld lesen oder einen angezeigten Eintrag mit seinen Daten verbinden. Derselbe Text kann als gewöhnliche Zeichen behandelt oder als HTML geparst werden, mit sehr unterschiedlichen Ergebnissen. Achte genau auf diese Unterschiede, damit Aktualisierungen den gewünschten Inhalt zeigen und externer Text sicher bleibt.

3.1 Wähle Text oder HTML für Inhaltsänderungen

Text und HTML sind unterschiedliche Eingaben. Einfacher Text soll als Zeichen erscheinen; HTML beschreibt Elemente, die der Browser aufbauen muss. Die Wahl zwischen beiden beeinflusst sowohl die Seitenstruktur als auch die Frage, ob externer Text unerwünschten Code ausführen kann.

Lies und ersetze Text

Bei <p id="msg">Total: <strong>3</strong> items</p> ist msg.textContent gleich „Total: 3 items“. Die Eigenschaft fügt Text aus den Nachfahrenelementen zusammen, ohne deren Tags aufzunehmen, und schließt durch CSS ausgeblendeten Text ein.

Das Setzen von textContent ersetzt alle Kindknoten durch einen Textknoten. Nach msg.textContent = "Cart is empty" existiert das <strong>-Kindelement nicht mehr innerhalb des Absatzes. Das Setzen von msg.textContent = "<b>Hi</b>" zeigt die tatsächlichen Zeichen „Hi“ an; es erstellt kein Element für Fettschrift.

Textwerte sind Zeichenketten. Enthält ein Zähler „4“, ergibt count.textContent + 1 den Wert „41“. Wandle vor dem Addieren um:

count.textContent = Number(count.textContent) + 1;

Die Addition ergibt die Zahl 5 und die Zuweisung zeigt ihre Textform „5“ an.

Lies Text entsprechend dem Layout

Bei einem gerenderten Element folgt innerText dem angezeigten Text und Layout. Die Eigenschaft lässt mit display: none ausgeblendete Nachfahrenelemente aus und enthält Zeilenumbrüche entsprechend dem Layout. Das Lesen kann eine Layoutberechnung erfordern. Verwende textContent für gewöhnliche Textarbeit und wähle innerText, wenn du den gerenderten Text benötigst. Ist das Element selbst losgelöst oder wird es nicht gerendert, greift innerText auf seinen Textinhalt zurück.

Parse HTML bewusst

innerHTML liest das Markup innerhalb eines Elements. Beim Setzen wird die Zeichenkette geparst und die Kindknoten werden ersetzt:

msg.innerHTML = "Total: <strong>5</strong> items";

Dadurch entsteht ein neues <strong>-Element. Die Methode eignet sich für Markup, das du geschrieben hast und kontrollierst. Verwende für Text von Nutzern oder aus externen Daten textContent und baue die Struktur mit createElement() auf.

Das Einfügen nicht vertrauenswürdigen HTMLs kann Cross-Site-Scripting (XSS) ermöglichen: Vom Angreifer kontrollierter Code wird im Browser des Besuchers ausgeführt. Ein eingeschleustes Bild kann ein onerror-Attribut tragen, das Code ausführt, wenn das Laden des Bildes fehlschlägt. Von innerHTML eingefügte Script-Tags werden nicht ausgeführt, aber das macht anderes eingeschleustes HTML nicht sicher. Das alleinige Blockieren von Script-Tags lässt diesen Angriffsweg offen.

Erhalte vorhandene Kindknoten beim Hinzufügen von Inhalt

list.innerHTML += "<li>New</li>" liest das vorhandene Markup, hängt eine Zeichenkette an und parst und ersetzt dann sämtliche Kindknoten. Ihre Objektidentität bleibt nicht erhalten. Eine Variable, die einen alten Kindknoten enthält, enthält weiterhin dieses losgelöste Objekt, und eingegebene Werte in ersetzten Eingabefeldern können verloren gehen. Verwende append() mit neuen Knoten oder insertAdjacentHTML("beforeend", markup) für vertrauenswürdiges Markup, um Inhalte hinzuzufügen, ohne vorhandene Kindknoten neu zu erstellen.

outerHTML enthält neben dem Inhalt auch das Tag des Elements selbst. Beim Setzen wird das Element selbst ersetzt. Eine gespeicherte Referenz verweist nach diesem Ersetzen weiterhin auf das alte, losgelöste Element; sie wechselt nicht automatisch zum neuen.

Wichtige Erkenntnisse

  • textContent verarbeitet einfachen Text und ersetzt bei einer Zuweisung die Kindknoten des Elements.
  • Wandle Text vor dem Rechnen in eine Zahl um.
  • innerText folgt dem gerenderten Layout; innerHTML parst Markup.
  • Halte nicht vertrauenswürdigen Text aus Zuweisungen heraus, die HTML parsen.
  • innerHTML += erstellt vorhandene Kindknoten neu; append() erhält sie.
  • Eine Zuweisung an outerHTML ersetzt das Element und lässt alte Referenzen auf das losgelöste Element verweisen.

3.2 Unterscheide Attribute von Objekteigenschaften

Ein Attribut ist ein Name mit einem Wert in HTML. Eine Eigenschaft gehört zum JavaScript-Objekt, das ein Element repräsentiert. Viele Standardattribute haben entsprechende Eigenschaften, aber diese können Werte verarbeiten oder eine andere Art von Zustand melden.

Arbeite über den Namen mit einem Attribut

Bei <img src="logo.png" alt="Company logo"> initialisiert der Browser Eigenschaften wie img.src und img.alt. Du kannst auch Methoden verwenden, die den Attributnamen als Zeichenkette entgegennehmen:

  • getAttribute(name) gibt eine Zeichenkette oder null zurück, wenn das Attribut fehlt.
  • setAttribute(name, value) fügt ein Attribut hinzu oder ändert es und speichert seinen Wert als Text.
  • hasAttribute(name) meldet, ob das Attribut vorhanden ist.
  • removeAttribute(name) entfernt es.

Zum Beispiel ändert link.setAttribute("href", "https://example.com/help") das Ziel eines Links. Fehlt das Attribut target, gibt link.getAttribute("target") den Wert null zurück, keine leere Zeichenkette.

Lies den Wert, den du tatsächlich benötigst

Auf einer Seite unter https://example.com/shop/ hat der Link <a href="/about"> den Attributwert „/about“. Seine Eigenschaft href ist die aufgelöste URL, "https://example.com/about". Lies das Attribut, wenn du den Wert genau wie geschrieben benötigst, und die Eigenschaft, wenn du die aufgelöste URL benötigst.

Eigenschaften können andere Typen als Zeichenketten haben. button.disabled ist ein boolescher Wert; input.maxLength ist eine Zahl. Attributmethoden geben weiterhin Zeichenketten oder null zurück. Eigenschaftsnamen sind außerdem JavaScript-Namen, bei denen zwischen Groß- und Kleinschreibung unterschieden wird: el.id funktioniert, während el.ID eine andere Eigenschaft ist und normalerweise undefined ergibt.

Die meisten Namen sind vertraut, aber es gibt Ausnahmen. Das HTML-Attribut class ist über className und classList zugänglich. Das Attribut for eines Labels entspricht seiner Eigenschaft htmlFor:

label.htmlFor = "email";

Das verbindet das Label mit dem Element, dessen ID „email“ ist.

Behandle boolesche Attribute nach ihrem Vorhandensein

Zu den booleschen Attributen gehören disabled, checked, required und readonly. Ist das Attribut vorhanden, ist es wahr, selbst wenn sein Text „false“ ist. Dieser Code deaktiviert eine Schaltfläche:

button.setAttribute("disabled", "false");

Um sie zu aktivieren, setze button.disabled = false oder rufe button.removeAttribute("disabled") auf. button.toggleAttribute("disabled", isBusy) fügt das Attribut hinzu, wenn isBusy wahr ist, und entfernt es, wenn der Wert falsch ist.

Beschreibe Bedienelemente barrierefrei

ARIA-Attribute liefern Informationen für assistive Technologien. Attributmethoden eignen sich, um sie zu setzen, etwa button.setAttribute("aria-label", "Close dialog"), um eine Schaltfläche zu benennen, die nur ein Symbol zeigt. Ihre Werte sind Zeichenketten; zum Beispiel ist der Wert für einen aufgeklappten Zustand „true“ oder „false“.

Verwende Eigenschaften für häufige Vorgänge wie img.src = "photo.jpg" oder input.disabled = true. Verwende Attributmethoden, wenn der Name in einer Variablen steht, der genaue geschriebene Wert wichtig ist oder das Attribut keine entsprechende Eigenschaft hat, die du verwendest.

Verfolge eine Eigenschaftsänderung bis zum HTML zurück
const field = document.createElement("input");
field.disabled = true;
console.log(field.hasAttribute("disabled"));
console.log(typeof field.disabled);
console.log(typeof field.getAttribute("disabled"));
field.removeAttribute("disabled");
console.log(field.disabled);

Die Ausgaben sind true, „boolean“, „string“ und false. Das Setzen der Eigenschaft fügt das boolesche Attribut hinzu. Das Lesen dieses Attributs gibt weiterhin Text zurück, obwohl die Eigenschaft boolesch ist. Das Entfernen setzt die Eigenschaft wieder auf falsch. Methode und Eigenschaft zeigen dasselbe Vorhandensein über unterschiedliche Werttypen an.

Wichtige Erkenntnisse

  • Attribute speichern HTML-Werte; Eigenschaften können typisierte oder verarbeitete Werte bereitstellen.
  • getAttribute() gibt eine Zeichenkette oder bei fehlendem Attribut null zurück.
  • Boolesche Attribute sind durch ihr Vorhandensein wahr, auch bei disabled="false".
  • Verwende Eigenschaftsnamen wie className und htmlFor, wenn sich die HTML-Namen unterscheiden.
  • ARIA-Werte sind Zeichenketten, die das Element für assistive Technologien beschreiben.

3.3 Verbinde Elemente mit Daten und lies Felder aus

Ein Element kann eine ID für die von ihm angezeigten Daten tragen, ohne diese ID auf dem Bildschirm anzuzeigen. Auch Formularsteuerelemente tragen Werte, aber ihr aktueller Inhalt wird über Eigenschaften gelesen. Beide Arten von Werten müssen vor Vergleichen oder Rechnungen oft umgewandelt werden.

Speichere benutzerdefinierte Daten mit Datenattributen

HTML-Namen, die mit data- beginnen, speichern Informationen für Skripte:

<li data-task-id="17" data-priority="high">Prepare slides</li>

Das Objekt dataset stellt diese Attribute bereit. Entferne das Präfix data- und ersetze jeden Bindestrich vor einem Kleinbuchstaben durch diesen Großbuchstaben: Aus data-task-id wird dataset.taskId. Aus data-priority wird dataset.priority.

li.dataset.dueDate = "2026-11-05";
delete li.dataset.priority;

Die Zuweisung erstellt data-due-date="2026-11-05". Das delete entfernt data-priority. Datenattribute lassen sich auch mit CSS-Attributselektoren wie '[data-priority="high"]' auswählen.

Ein frei erfundenes Attribut wie taskid="17" ist ungültiges HTML und erstellt keine Eigenschaft li.taskid. getAttribute("taskid") kann es weiterhin lesen, aber data-task-id ist die korrekte Form für benutzerdefinierte Daten.

Wandle Zeichenkettenwerte bewusst um

li.dataset.taskId ist „17“, eine Zeichenkette. li.dataset.taskId === 17 ist falsch, weil sich die Typen unterscheiden. Sind die IDs in den Daten Zahlen, verwende Number(li.dataset.taskId) === 17. Ein fehlendes Datenattribut ergibt undefined. Die Zuweisung li.dataset.count = 3 speichert den Text „3“.

Das schafft eine nützliche Verbindung von einem angezeigten Eintrag zurück zu seinem Objekt:

const id = Number(li.dataset.taskId);
const task = tasks.find(task => task.id === id);

Der Vergleich verwendet nun zwei Zahlen. Hat kein Objekt diese ID, gibt find() den Wert undefined zurück; prüfe das, bevor du seine Eigenschaften liest.

Lies den aktuellen Wert eines Felds

Ein <input> enthält den eingegebenen Wert nicht als Textinhalt. Lies input.value, eine Zeichenkette, oder weise der Eigenschaft einen Wert zu, um das Feld zu ändern. input.value = "" leert es.

Bei <input id="qty" value="1"> ist qty.value gleich „3“, nachdem der Nutzer 3 eingegeben hat, aber qty.getAttribute("value") ist weiterhin „1“. Das Attribut liefert den Anfangswert; die Eigenschaft liefert den aktuellen Wert. Ein Kontrollkästchen funktioniert ähnlich: Seine Eigenschaft checked meldet seinen aktuellen booleschen Zustand, während das Attribut den anfänglichen Auswahlzustand beschreibt.

Verwende für jedes Bedienelement den richtigen Wert

Selbst <input type="number"> hat einen value als Zeichenkette. Ist die Menge „3“ und wiegt jeder Artikel 0,25 kg, ergibt Number(qty.value) * 0.25 den Wert 0,75 kg. Aber qty.value + 1 ergibt „31“, weil + eine Zeichenkette und eine Zahl verkettet. Ein <select> gibt den Wert der ausgewählten Option über select.value zurück. Lies bei einem Kontrollkästchen checkbox.checked, nicht checkbox.value, wenn du wissen musst, ob es ausgewählt ist.

Wichtige Erkenntnisse

  • dataset bildet data-task-id auf taskId ab und speichert Zeichenkettenwerte.
  • Verwende delete auf einer dataset-Eigenschaft, um ihr Datenattribut zu entfernen.
  • Wandle Daten-IDs vor einem strikten Vergleich mit numerischen IDs um.
  • Lies den aktuellen Inhalt von input und select über value.
  • Lies den aktuellen Auswahlzustand eines Kontrollkästchens über checked.
  • Die anfänglichen Attribute value und checked können von den aktuellen Eigenschaften der Bedienelemente abweichen.
4

Steuere Aussehen und Sichtbarkeit

JavaScript kann das Aussehen einer Seite ändern, indem es Klassen umschaltet, einen berechneten Inline-Wert setzt oder einen Abschnitt ausblendet. Diese Möglichkeiten wirken mit dem CSS zusammen, das bereits auf der Seite steht. Lerne, welcher Zustand in eine Klasse gehört, welche Werte Einheiten benötigen und wie du den vom Browser angewandten Stil liest. Das Ein- und Ausblenden wirkt sich auch auf das Layout und assistive Technologien aus. Halte daher sichtbare Bereiche und ihre Attribute für Barrierefreiheit aufeinander abgestimmt.

4.1 Schalte Klassen um, ohne die Grundgestaltung zu verlieren

Belasse feste visuelle Regeln im CSS und lass JavaScript dann die Klassen ändern, die diese Regeln auswählen. Eine Klasse kann einen Zustand wie „erledigt“, „aktiv“ oder „Fehler“ ausdrücken, ohne die zugehörigen Farben und Dekorationen im Code zu wiederholen.

Füge Klassentoken hinzu und entferne sie

Angenommen, das Stylesheet enthält:

.done { text-decoration: line-through; color: #888; }

item.classList.add("done") wendet das Erscheinungsbild für erledigte Einträge an. item.classList.remove("done") entfernt diesen Zustand und lässt andere Klassen unverändert. Beide Methoden akzeptieren mehrere Namen; das Hinzufügen einer vorhandenen oder das Entfernen einer fehlenden Klasse ist unproblematisch.

contains("done") gibt einen booleschen Wert zurück. replace("wide", "narrow") ersetzt eine vorhandene Klasse durch eine andere. toggle("active") fügt eine fehlende Klasse hinzu oder entfernt eine vorhandene und gibt zurück, ob die Klasse danach vorhanden ist.

Verfolge eine Klassenänderung

Beginne mit <div class="card">:

card.classList.add("active", "wide");
const active = card.classList.toggle("active");
const replaced = card.classList.replace("wide", "narrow");

Nach der ersten Zeile lauten die Klassen „card active wide“. Das Umschalten entfernt „active“, sodass active gleich false ist und die Klassen zu „card wide“ werden. Das Ersetzen von „wide“ hinterlässt „card narrow“ und gibt true zurück. Ein späteres card.classList.contains("active") ist false.

Setze eine Klasse anhand einer Bedingung

Wenn die Daten den gewünschten Zustand vorgeben, übergib ein zweites Argument:

row.classList.toggle("overdue", daysLeft < 0);

Ein negativer Wert für daysLeft sorgt dafür, dass die Klasse vorhanden ist; andernfalls fehlt sie. Wiederholst du den Aufruf, bleibt dieser Zustand erhalten. Ein einfaches toggle("overdue") würde ihn bei jedem Aufruf umkehren.

Erhalte den Rest des Klassenattributs

className ist die vollständige Klassenzeichenkette. card.className = "active" ersetzt alle vorhandenen Klassen, einschließlich „card“. Verwende diese Zuweisung, wenn du alle Klassen ersetzen möchtest; verwende classList für Änderungen einzelner Zustände.

Übergib reine Klassennamen ohne Satzzeichen aus CSS-Selektoren. classList.add(".active") fügt ein Token hinzu, das tatsächlich einen Punkt enthält; es ist nicht die Klasse, auf die .active passt. Ein einzelnes Argument darf keine Leerzeichen enthalten: classList.add("big red") löst einen InvalidCharacterError aus. Schreibe classList.add("big", "red") für zwei Klassen.

Prüfe das CSS, wenn sich das Aussehen nicht ändert

Hat eine Klasse keine sichtbare Wirkung, untersuche ihr Token und ihre Regel in den DevTools. Prüfe, ob eine Regel fehlt oder falsch geschrieben ist und ob im Bereich „Styles“ übersteuerte Deklarationen durchgestrichen sind.

Wichtige Erkenntnisse

  • classList ändert einzelne Klassentoken und erhält andere Klassen.
  • toggle(name) gibt zurück, ob die Klasse danach vorhanden ist.
  • toggle(name, condition) setzt eine Klasse anhand von Daten, ohne sie bei jeder Ausführung umzukehren.
  • Eine Zuweisung an className ersetzt die gesamte Klassenzeichenkette.
  • Übergib reine Namen getrennt, ohne Selektorpunkte oder Leerzeichen innerhalb eines Tokens.

4.2 Setze berechnete Stile und lies angewandte Stile aus

Verwende Klassen für feste Designs und Inline-Stile für berechnete Werte. Das Objekt style liest und schreibt Inline-Deklarationen, nicht alle Regeln, die ein Element beeinflussen.

Schreibe CSS-Werte über style

CSS-Namen mit Bindestrichen werden zu JavaScript-Eigenschaften in camelCase. Aus background-color wird backgroundColor, aus font-size wird fontSize und aus z-index wird zIndex:

box.style.backgroundColor = "gold";
box.style.width = "250px";

Stilwerte sind Zeichenketten. Gib eine Einheit an, wenn die Eigenschaft sie benötigt. Auf einer Seite im Standardmodus wird die Zuweisung box.style.width = 250 ignoriert, weil eine Breite ungleich null eine CSS-Einheit benötigt. Die Zeichenkette „0“ ist für eine Breite von null gültig.

style.setProperty() erwartet stattdessen die CSS-Schreibweise:

box.style.setProperty("background-color", "gold");
document.documentElement.style.setProperty("--accent", "#0a7d5a");

Die benutzerdefinierte Eigenschaft am Wurzelelement liefert den Wert für Regeln, die auf var(--accent) verweisen.

Wandle ein Rechenergebnis in einen CSS-Wert um

Ein Fortschrittsbalken zeigt 3 erledigte Aufgaben von 8:

const percent = (3 / 8) * 100;
bar.style.width = `${percent}%`;

Der Anteil 0,375 wird zu 37,5 Prozent. Das Template-Literal liefert „37.5%“ einschließlich der benötigten Einheit.

Entferne eine vorübergehende Überschreibung

Setze box.style.backgroundColor = "" oder rufe box.style.removeProperty("background-color") auf, um diese Inline-Deklaration zu entfernen. Der Browser wendet dann die verbleibenden Stylesheet-Regeln an. Verwende bei removeProperty() den CSS-Namen mit Bindestrichen.

Sei vorsichtig mit style.cssText. Die Zuweisung box.style.cssText = "color: red" ersetzt den gesamten Inline-Stil, sodass eine vorhandene Inline-Breite verloren geht. Das Ändern einer einzelnen Stileigenschaft lässt die anderen Inline-Deklarationen unverändert.

Lies, was der Browser anwendet

Färbt ein Stylesheet einen Absatz rot, hat dieser aber keine Inline-Farbe, ist p.style.color eine leere Zeichenkette. Verwende getComputedStyle(p).color für den angewandten Wert, häufig „rgb(255, 0, 0)“. Berechnete Werte sind schreibgeschützt; ändere die Klasse oder Inline-Deklaration, um das Aussehen zu ändern.

Inline-Deklarationen übersteuern gewöhnliche Stylesheet-Regeln, aber anwendbare !important-Deklarationen können Vorrang haben. Wenn eine Klassenänderung wirkungslos erscheint, prüfe, ob eine Inline-Überschreibung übrig geblieben ist.

Wichtige Erkenntnisse

  • style liest und schreibt Inline-Deklarationen; camelCase entspricht CSS-Namen mit Bindestrichen.
  • Gib in CSS-Wertzeichenketten Einheiten an, wenn sie benötigt werden.
  • setProperty() und removeProperty() erwarten CSS-Namen mit Bindestrichen.
  • Entferne eine Inline-Deklaration, damit Stylesheet-Regeln wieder gelten.
  • getComputedStyle() meldet angewandte Werte, einschließlich der Stile aus CSS-Regeln.

4.3 Blende Inhalte aus und halte ihren Zustand eindeutig

Wenn du einen Bereich ausblendest, bleibt er im DOM und kann mit seinem vorhandenen Inhalt und seinen Feldwerten wieder angezeigt werden. Beim Entfernen verlässt er den Baum. Wähle das Ausblenden für einen Bereich, der wieder erscheinen soll, und das Entfernen für einen Eintrag, dessen Daten nicht mehr existieren.

Verwende die Eigenschaft hidden

panel.hidden = true setzt den gewöhnlichen ausgeblendeten Zustand. Der Standardstil des Browsers blendet den Bereich aus, ohne Platz im Layout zu lassen. panel.hidden = false entfernt diesen Zustand und zeigt ihn wieder an.

Ein Stylesheet kann diesen Standard übersteuern. Zum Beispiel kann .panel { display: flex; } einen ausgeblendeten Bereich sichtbar machen. Wenn der ausgeblendete Zustand immer Vorrang haben soll, füge Folgendes ein:

[hidden] { display: none !important; }

Alternativ kannst du die Sichtbarkeit mit einer CSS-Klasse steuern. Bei .is-hidden { display: none; } fügt menu.classList.toggle("is-hidden", !isOpen) die ausblendende Klasse hinzu, wenn das Menü geschlossen ist. Prüfe das Stylesheet, wenn die Klasse vorhanden ist, aber eine andere display-Deklaration Vorrang hat.

Vergleiche drei Arten des Ausblendens

display: none entfernt den Platz des Elements im Layout und verbirgt es vor Screenreadern. visibility: hidden macht es unsichtbar, erhält aber seinen Platz und verbirgt es ebenfalls vor Screenreadern. opacity: 0 macht es transparent, erhält aber seinen Platz; es kann weiterhin angeklickt werden und bleibt für Screenreader zugänglich. Transparenz allein ist daher eine schlechte Möglichkeit, einen Bereich zu schließen, der nicht mehr zugänglich sein soll.

Diese Auswirkungen betreffen Sichtbarkeit und Layout, nicht das Löschen. Ein ausgeblendetes Eingabefeld kann seinen eingegebenen Wert weiterhin behalten, weil dasselbe Eingabeobjekt im Baum bleibt.

Halte die Beschreibung des Bedienelements aktuell

Eine Schaltfläche für einen aufklappbaren Bereich sollte angeben, ob dieser aufgeklappt ist. Setze aria-expanded auf die Zeichenkette „true“, wenn er geöffnet ist, und auf „false“, wenn er geschlossen ist. Leite diesen Wert und die Sichtbarkeit des Bereichs aus demselben Zustand ab.

Für einen Antwortbereich, der als <div id="answer-1" hidden> beginnt, mit Referenzen namens answer und button, führe Folgendes aus:

const willOpen = answer.hidden;
answer.hidden = !willOpen;
button.setAttribute("aria-expanded", String(willOpen));

Anfangs ist answer.hidden gleich true, also ist willOpen wahr. Die Zuweisung setzt hidden auf falsch und zeigt den Bereich an. Das Attribut der Schaltfläche wird zu „true“. Führst du dieselben Anweisungen erneut aus, ist hidden zu Beginn falsch, der Bereich wird ausgeblendet und „false“ in das Attribut geschrieben.

Untersuche eine Abweichung

Wenn die Schaltfläche „aufgeklappt“ meldet, während der Bereich ausgeblendet ist, wurden die beiden Werte nicht gemeinsam aktualisiert. Ist hidden wahr, der Bereich aber weiterhin sichtbar, untersuche sein berechnetes display und die dafür verantwortliche CSS-Regel. Das erste Problem ist ein inkonsistenter Anwendungszustand; beim zweiten übersteuert ein Stil den ausgeblendeten Zustand. Wenn du sowohl die DOM-Eigenschaften als auch das angewandte CSS liest, kannst du sie unterscheiden.

Wichtige Erkenntnisse

  • hidden behält Inhalte im DOM und blendet sie mit dem Standardstil aus.
  • Eine explizite display-Regel kann hidden übersteuern; prüfe die beabsichtigte Regel oder setze sie durch.
  • display: none entfernt den Platz; visibility: hidden erhält ihn.
  • opacity: 0 erhält die Interaktion und die Zugänglichkeit für Screenreader.
  • Aktualisiere aria-expanded anhand desselben geöffneten Zustands wie den Bereich.
5

Erstelle und ändere Seitenstrukturen

Die Struktur einer Seite kann sich ändern, während sie geöffnet ist. Erstelle ein Element im Speicher, fülle es und füge es an der richtigen Stelle im Baum ein. Dieselben Einfügemethoden können einen vorhandenen Knoten verschieben, sodass das zweimalige Hinzufügen einer Referenz keine zwei Kopien erstellt. Entfernen, Ersetzen und Klonen verändern den Baum und die Referenzen deines Skripts auf unterschiedliche Weise. Wenn du diese Referenzen verfolgst, verstehst du, warum eine alte Variable manchmal auf losgelöste Inhalte verweist.

5.1 Erstelle einen Knoten, fülle ihn und füge ihn ein

Ein neues Element erscheint nicht allein dadurch, dass du es erstellt hast. Erstelle zuerst das Objekt, gib ihm dann Inhalt und Attribute und füge es schließlich in das Dokument ein. Vor dem Einfügen kannst du eine vollständig verschachtelte Struktur im Speicher zusammenstellen.

Erstelle einen vollständigen Eintrag
const li = document.createElement("li");
li.textContent = "Water the plants";
li.className = "task";
li.dataset.id = "4";
document.querySelector("#tasks").append(li);

createElement("li") erstellt ein leeres Element. Die nächsten Zeilen füllen es; die letzte fügt es als letzten Kindknoten der vorhandenen Aufgabenliste ein. Es entsteht <li class="task" data-id="4">Water the plants</li>. Der Aufruf benötigt einen Tag-Namen, kein Markup: createElement("<li>") löst einen InvalidCharacterError aus. Setze Klassen und Attribute nach dem Erstellen.

Erstelle für verschachtelten Inhalt ein span-Element für den Titel und eine Schaltfläche getrennt, setze ihren Text und rufe li.append(title, button) auf. Füge dann den zusammengesetzten Eintrag in die Liste ein. document.createTextNode("…") erstellt Text direkt; auch die Übergabe einer Zeichenkette an append() fügt einen Textknoten ein.

Wähle eine Einfügeposition
  • parent.append(...) fügt nach den vorhandenen Kindknoten hinzu.
  • parent.prepend(...) fügt vor den vorhandenen Kindknoten hinzu.
  • element.before(...) fügt vorherige Geschwisterknoten hinzu.
  • element.after(...) fügt nachfolgende Geschwisterknoten hinzu.

Jede Methode akzeptiert mehrere Knoten und Zeichenketten. Zeichenketten werden als Text behandelt, sodass list.append("<li>New</li>") keinen Eintrag erstellt. Die spitzen Klammern erscheinen als Zeichen innerhalb der Liste.

Ältere Methoden kommen weiterhin im Code vor. appendChild(node) akzeptiert einen Knoten und gibt ihn zurück; die Methode akzeptiert keine Zeichenkette. append() gibt undefined zurück. parent.insertBefore(newNode, referenceNode) fügt einen Knoten vor einem vorhandenen Kindknoten ein; mit null als Referenz wird am Ende hinzugefügt.

Verstehe Verschieben und Kopieren

Ein Knoten kann im Baum nur einen Platz einnehmen. Das Einfügen eines vorhandenen Knotens verschiebt ihn. Bei einer Liste in der Reihenfolge a, b, c verschiebt list.prepend(list.lastElementChild) c an den Anfang, sodass c, a, b entsteht. Am Ende bleibt kein zweites c zurück.

Das erklärt auch einen häufigen Schleifenfehler: Wenn du ein <li> außerhalb einer Schleife erstellst und wiederholt anhängst, bleibt ein Eintrag übrig. Jeder Durchlauf ändert und verschiebt dasselbe Objekt. Erstelle bei jedem Durchlauf ein neues Element, wenn die Seite mehrere Einträge benötigt, oder erstelle separate Klone.

Füge vertrauenswürdiges Markup neben vorhandenem Inhalt ein

insertAdjacentHTML(position, markup) parst HTML, ohne vorhandene Kindknoten zu ersetzen. Die vier Positionsnamen sind "beforebegin" und "afterend" für Geschwisterknoten außerhalb des Elements sowie "afterbegin" und "beforeend" für Kindknoten innerhalb des Elements. list.insertAdjacentHTML("beforeend", "<li>New</li>") hängt einen geparsten Eintrag an. Verwende dies nur für vertrauenswürdiges Markup; externer Text gehört in textContent. insertAdjacentElement() und insertAdjacentText() verwenden dieselben Positionsnamen für ein Element beziehungsweise einfachen Text.

Wichtige Erkenntnisse

  • Erstellen, Füllen und Einfügen sind getrennte Schritte.
  • append/prepend fügen Kindknoten hinzu; before/after fügen Geschwisterknoten hinzu.
  • Die Übergabe einer Zeichenkette an append() fügt Text ein, ohne HTML zu parsen.
  • Das Einfügen eines vorhandenen Knotens verschiebt ihn, statt ihn zu kopieren.
  • Erstelle bei jedem Schleifendurchlauf einen neuen Eintrag, wenn du mehrere Objekte benötigst.
  • appendChild() akzeptiert einen Knoten und gibt ihn zurück; append() akzeptiert mehrere Eingaben und gibt undefined zurück.
  • insertAdjacentHTML() erhält vorhandene Kindknoten, parst seine Eingabe aber weiterhin als HTML.

5.2 Entferne, ersetze und klone die richtigen Objekte

Das Entfernen eines Elements ändert den Baum, löscht aber nicht jede Referenz auf dieses Objekt. Beim Ersetzen gibt es einen ähnlichen Unterschied: Das neue Objekt nimmt seinen Platz ein, während gespeicherte Variablen weiterhin auf das alte verweisen können.

Entferne ein Element oder mehrere Treffer

element.remove() löst dieses Element aus dem Baum. parent.removeChild(child) ist die ältere Form über den Elternknoten und gibt den entfernten Knoten zurück. Enthält eine Variable den Knoten weiterhin, kann das Skript ihn später lesen oder wieder einfügen.

Um erledigte Aufgaben zu entfernen, wähle eine statische Sammlung aus und durchlaufe sie:

document.querySelectorAll(".task.done")
  .forEach(task => task.remove());

Bei fünf Aufgaben, von denen zwei als erledigt markiert sind, bleiben drei übrig. Das Entfernen eines Elements ändert nicht, welche Referenzen die statische NodeList enthält, sodass die Schleife beide ausgewählten Aufgaben besucht.

Zähle nicht vorwärts durch eine schrumpfende dynamische Liste

list.children ist dynamisch. Bei sechs Kindknoten entfernt eine vorwärts laufende Schleife, die items[i] entfernt, nur drei. Nach dem ersten Entfernen rückt das zweite Element auf Index 0, aber i geht zu 1 weiter. Der nächste ursprüngliche Kindknoten wird übersprungen und dieselbe Verschiebung wiederholt sich.

Erstelle eine Momentaufnahme, bevor du alle aktuellen Kindknoten entfernst:

Array.from(list.children).forEach(item => item.remove());

Um einen Container lediglich zu leeren, ist list.replaceChildren() übersichtlicher. Auch das Setzen von list.textContent = "" oder list.innerHTML = "" leert ihn. Eine leere Zeichenkette parst keinen externen Inhalt.

Ersetze einen einzelnen Knoten oder alle Kindknoten

old.replaceWith(newElement) setzt einen neuen Knoten an die Stelle des alten. Bei <p id="status">Loading…</p> ersetzt document.querySelector("#status").replaceWith(list) die Meldung durch die Liste. parent.replaceChildren(a, b, c) ersetzt alle Kindknoten des Elternknotens in einem Vorgang und erhält dabei den Elternknoten selbst.

Dieser Unterschied ist für gespeicherte Referenzen wichtig. Eine Variable, die den Elternknoten enthält, bleibt nach replaceChildren() erhalten, aber Referenzen auf die entfernten Kindknoten verweisen nun auf losgelöste Objekte. Das Ersetzen eines Containers mit replaceWith() löst auch diesen Container aus dem Baum.

Kopiere das Element mit oder ohne Nachfahrenknoten

element.cloneNode(true) erstellt eine tiefe Kopie, einschließlich Nachfahrenknoten und Attributen. cloneNode() oder cloneNode(false) kopiert das Element und seine Attribute ohne seine Kindknoten. Ein geklonter Listeneintrag ohne Nachfahrenknoten enthält keinen Text des ursprünglichen Eintrags.

Ein Klon ist anfangs losgelöst und muss eingefügt werden. Er übernimmt auch die ID des Originals. Gib ihm eine neue ID oder entferne das Attribut, bevor du ihn auf derselben Seite platzierst, damit die Auswahl über IDs zuverlässig bleibt.

Behandle optionale Elemente

Wenn eine Suche fehlschlagen kann, rufe nicht sofort eine Methode auf ihrem Ergebnis auf. document.querySelector("#promo").remove() löst einen Fehler aus, wenn kein Werbebereich vorhanden ist. document.querySelector("#promo")?.remove() tut in diesem Fall sicher nichts. Bei einem benötigten Container ist ein fehlendes Ergebnis ein nützliches Signal, Selektor und Ausführungszeitpunkt des Skripts zu prüfen, bevor du eine strukturelle Änderung versuchst.

Wichtige Erkenntnisse

  • remove() löst einen Knoten aus dem Baum; über eine gespeicherte Referenz kannst du ihn weiterhin verwenden oder erneut einfügen.
  • Verwende eine statische Liste, wenn du mehrere ausgewählte Elemente entfernst.
  • replaceChildren() erhält den Container und ersetzt oder entfernt seine Kindknoten.
  • replaceWith() ersetzt den ausgewählten Knoten selbst.
  • cloneNode(true) kopiert Nachfahrenknoten; ein flacher Klon lässt sie aus.
  • Klonen kopiert IDs, ändere oder entferne daher eine kopierte ID vor dem Einfügen.
6

Wandle Daten in eine Seite um

Arrays beschreiben, was eine Seite anzeigen soll; beim Rendern werden diese Beschreibungen in Elemente umgewandelt. Beginne mit einem Eintrag, erweitere das Muster auf Listen und Tabellen und organisiere dann wiederholtes Markup mit Fragmenten oder Templates. Eine Renderfunktion macht spätere Aktualisierungen bei Datenänderungen vorhersagbar. Unterscheide das ursprüngliche Array, die ausgewählte Ansicht und die angezeigten Elemente, damit Filterung, Sortierung, leere Ergebnisse und Zusammenfassungen konsistent bleiben.

6.1 Rendere Arrayeinträge als Listeneinträge und Tabellenzeilen

Rendern bedeutet, Daten in eine sichtbare DOM-Struktur umzuwandeln. Behalte das Array als Quelle und erstelle für jedes Objekt ein Element. Setze Datenwerte in textContent, damit sie Text bleiben, selbst wenn sie spitze Klammern enthalten.

Erstelle für jedes Objekt ein Element

Verwende diese Buchobjekte:

const books = [
  { id: 1, title: "Dune", pages: 412 },
  { id: 2, title: "Emma", pages: 474 },
  { id: 3, title: "Beloved", pages: 324 }
];
function createBookItem(book) {
  const li = document.createElement("li");
  li.dataset.id = String(book.id);
  li.textContent = `${book.title} (${book.pages} pages)`;
  return li;
}
const list = document.querySelector("#books");
list.append(...books.map(createBookItem));

map() ruft die Erstellungsfunktion einmal pro Buch auf und liefert drei getrennte Elemente. Die Spread-Syntax übergibt diese Elemente als separate Argumente an append(). Die Anzeige lautet „Dune (412 pages)“, „Emma (474 pages)“ und „Beloved (324 pages)“. Die Seitenzahlen ergeben zusammen 1.210.

Ohne Spread erhält list.append(books.map(createBookItem)) ein einzelnes Array. Die Methode wandelt dieses Array in Text mit Zeichenketten wie „[object HTMLLIElement]“ um, statt die Eintragselemente einzufügen.

Die gespeicherte ID verbindet das angezeigte Element mit den Daten. Lies Number(li.dataset.id), bevor du den Wert mit numerischen Buch-IDs vergleichst, und verwende dann books.find(book => book.id === id).

Behandle fehlende und leere Daten

Fehlt ein optionales Autorenfeld, zeigt eine direkte Interpolation „undefined“ an. Verwende book.author ?? "Unknown author" als Ersatzwert, wenn das Feld null oder undefined ist. Der Nullish-Coalescing-Operator lässt andere Werte, einschließlich 0 und einer leeren Zeichenkette, unverändert.

Ist das Array leer, zeige eine Meldung wie „Noch keine Bücher“ an. Ein leeres Ergebnis sollte dem Nutzer mitteilen, dass derzeit keine Einträge vorhanden sind. Ersetze beim erneuten Rendern die alte Anzeige, damit eine frühere Meldung oder frühere Einträge nicht neben dem neuen Ergebnis stehen bleiben.

Verstehe die Vorgehensweise mit HTML-Zeichenketten

Ein vertrauenswürdiges Array kann auf HTML-Zeichenketten abgebildet und vor der Zuweisung an innerHTML mit join("") zusammengefügt werden. Das Zusammenfügen entfernt die Kommas, die die Umwandlung des Arrays in eine Zeichenkette andernfalls einfügen würde. Bei dieser Vorgehensweise wird jeder interpolierte Wert als HTML geparst. Verwende das Erstellen von Elementen, wenn Werte aus externen Quellen stammen können.

Erstelle eine gültige Tabellenstruktur

Erstelle für Tabellendaten ein <tr> pro Objekt und ein <td> für jedes angezeigte Feld. Hänge die Zeilen an den <tbody> der Tabelle an. Für Messwerte aus Oslo bei 4,25 °C und Kairo bei 28,5 °C kann die Temperaturzelle reading.temp.toFixed(1) verwenden: Die Anzeige lautet „4.3“ und „28.5“. toFixed() gibt eine Zeichenkette mit den angeforderten Dezimalstellen zurück. toLocaleString() formatiert dagegen für das Gebietsschema des Nutzers, das ein Dezimalkomma verwenden kann. Formatiere erst bei der Anzeige, damit die numerischen Daten für Berechnungen verfügbar bleiben.

Erstelle beide Zellen vor dem Einfügen der Zeile

Für einen vorhandenen leeren Tabellenkörper namens tbody rendert dies die Messwerte:

const readings = [{ city: "Oslo", temp: 4.25 }, { city: "Cairo", temp: 28.5 }];
const rows = readings.map(reading => {
  const row = document.createElement("tr");
  const city = document.createElement("td");
  const temperature = document.createElement("td");
  city.textContent = reading.city;
  temperature.textContent = reading.temp.toFixed(1) + " °C";
  row.append(city, temperature);
  return row;
});
tbody.replaceChildren(...rows);

Jeder Durchlauf erstellt eine neue Zeile und zwei neue Zellen. Wenn du beide Zellen vor dem Anhängen der Zeile füllst, bleibt die Reihenfolge der Felder eindeutig. Die Spread-Syntax übergibt die beiden Zeilenknoten aus rows getrennt; das abschließende Ersetzen entfernt auch frühere Zeilen.

Wichtige Erkenntnisse

  • Erstelle für jedes Datenobjekt ein eigenes Element und fülle Werte mit textContent ein.
  • Verwende Spread für ein Array aus Knoten, wenn du sie an append() übergibst.
  • Verwende Datenattribute, um angezeigte Elemente mit Objekten zu verbinden.
  • Stelle Meldungen für Leerzustände und Ersatzwerte für null oder undefined bereit.
  • Setze Tabellenzeilen in tbody und Felder in Zellen.
  • toFixed() gibt Anzeigetext zurück; behalte numerische Daten für Berechnungen.

6.2 Setze wiederholte Inhalte vor dem Einfügen zusammen

Wenn eine Liste viele Einträge enthält, erstelle den neuen Inhalt außerhalb der Seite und füge ihn gemeinsam ein. Ein DocumentFragment gruppiert Knoten, ohne ein umschließendes Element hinzuzufügen. Mit einem template-Element kannst du eine wiederholte Struktur in HTML schreiben und für jedes Objekt eine neue Kopie füllen.

Sammle Knoten in einem Fragment
const fragment = document.createDocumentFragment();
for (const book of books) {
  fragment.append(createBookItem(book));
}
list.append(fragment);

Das Fragment beginnt außerhalb des Dokuments. Jeder neue Eintrag wird zu seinem Kindknoten. Das Anhängen des Fragments verschiebt seine Kindknoten in ihrer bisherigen Reihenfolge in die Liste; das Fragment selbst wird nicht als umschließendes Element eingefügt. Nachdem 100 Einträge in eine leere Liste übertragen wurden, hat die Liste 100 Kindknoten und das Fragment 0.

Dieses Muster bündelt das Einfügen und hält den Erstellungscode übersichtlich. Es verspricht keinen bestimmten Geschwindigkeitsgewinn. Ein Array erstellter Knoten funktioniert ebenfalls: list.append(...items) fügt sie hinzu, während list.replaceChildren(...items) den aktuellen Inhalt durch sie ersetzt.

Definiere wiederholtes Markup in einem Template
<template id="book-row">
  <li class="book"><span class="title"></span>
    (<span class="pages"></span> pages)</li>
</template>

Der Browser parst dieses Markup, ohne es anzuzeigen. Der Inhalt liegt in einem separaten DocumentFragment unter template.content. Eine Suche auf Dokumentebene durchsucht dieses Fragment nicht. Wähle das Template aus, klone seinen Inhalt und suche dann innerhalb des Klons:

const template = document.querySelector("#book-row");
const clone = template.content.cloneNode(true);
clone.querySelector(".title").textContent = book.title;
clone.querySelector(".pages").textContent = book.pages;
const item = clone.firstElementChild;
list.append(clone);

Titel und Seitenzahl werden vor dem Einfügen ausgefüllt. item speichert eine Referenz auf das neue <li>. Nach dem Anhängen ist clone leer, weil seine Kindknoten verschoben wurden, aber item verweist weiterhin auf das eingefügte Element.

Erhalte die wiederverwendbare Quelle

Hänge jedes Mal eine Kopie an. Der Aufruf list.append(template.content) verschiebt die Quellknoten aus dem Template. Eine spätere Suche innerhalb von template.content gibt dann null zurück und der nächste Versuch, den fehlenden Titel zu füllen, löst einen Fehler aus. Das Quell-Template sollte für spätere Bücher verfügbar bleiben.

Fülle für viele Kopien jedes geklonte Fragment, hänge diese Kopien an ein Sammelfragment an und füge dann die Sammlung ein. Ein Fragment kann die Kindknoten eines anderen Fragments ebenso aufnehmen wie eine Liste.

Wähle eine lesbare Erstellungsmethode

createElement() eignet sich für eine kleine Struktur oder eine, die sich je nach Eintrag stark unterscheidet. Ein Template eignet sich für größeres wiederholtes Markup, das sich als HTML leichter bearbeiten lässt. Füge in beiden Fällen externe Werte als Text ein. Eine HTML-Zeichenkette eignet sich für vertrauenswürdiges Markup, aber die Interpolation darin löst weiterhin das Parsen von HTML aus. Wähle die Erstellungsmethode anhand der Struktur, die du pflegen musst, und behalte dabei die Reihenfolge Erstellen oder Klonen, Füllen und Einfügen bei.

Sammle gefüllte Kopien für ein einmaliges Ersetzen

Mit dem obigen Buch-Template und einem vorhandenen books-Array:

const group = document.createDocumentFragment();
for (const book of books) {
  const copy = template.content.cloneNode(true);
  copy.querySelector(".title").textContent = book.title;
  copy.querySelector(".pages").textContent = book.pages;
  group.append(copy);
}
list.replaceChildren(group);

Jede gefüllte Kopie überträgt ihren Eintrag in group. Die letzte Zeile ersetzt den Listeninhalt durch diese Einträge und leert group. Das ursprüngliche Template bleibt währenddessen unverändert, sodass die Funktion den Aufbau für ein späteres Array wiederholen kann.

Wichtige Erkenntnisse

  • Das Anhängen eines Fragments verschiebt seine Kindknoten und lässt das Fragment leer zurück.
  • Ein Fragment gruppiert Knoten, ohne ein umschließendes Element auf der Seite zu erstellen.
  • Template-Inhalte werden geparst, liegen aber außerhalb des angezeigten Dokumentbaums.
  • Klone template.content für jeden Eintrag und fülle den Klon vor dem Einfügen.
  • Speichere die Referenz auf den Eintrag, bevor das enthaltende Fragment geleert wird.

6.3 Halte gerenderte Ansichten mit den Daten aktuell

Verwende Daten als einzige Source of Truth. Eine Renderfunktion leitet aus dem aktuellen Array eine Anzeige ab. Rufe sie auf, nachdem du das Array oder ein Objekt darin geändert hast.

Ersetze die Anzeige bei jedem Rendern

Angenommen, tasks enthält vier Objekte, von denen genau eines erledigt ist, und Aufgabe 2 existiert und ist unerledigt. Eine Renderfunktion kann neue Einträge und eine Zusammenfassung erstellen:

function render() {
  const items = tasks.map(task => {
    const li = document.createElement("li");
    li.dataset.id = String(task.id);
    li.textContent = task.text;
    li.classList.toggle("done", task.done);
    return li;
  });
  list.replaceChildren(...items);
  const doneCount = tasks.filter(task => task.done).length;
  summary.textContent = `${doneCount} of ${tasks.length} done`;
}

Nach tasks.push({ id: 5, text: "Book dentist", done: false }); render(); hat die Liste fünf Einträge und die Zusammenfassung lautet „1 of 5 done“. Das Setzen von tasks.find(task => task.id === 2).done = true; render(); ändert sie zu „2 of 5 done“.

Das Ersetzen der Kindknoten ist hier wesentlich. Würde die Funktion alle Einträge nur anhängen, würde ein zweimaliger Aufruf die Anzeige verdoppeln. Auch das Entfernen nur eines DOM-Eintrags ist vorübergehend: Bleibt sein Objekt im Array, bringt das Rendern ihn zurück. Wenn tasks mit let deklariert ist, lösche mit tasks = tasks.filter(task => task.id !== id) aus den Daten und rendere erneut.

Leite eine Ansicht ab, ohne die Quelle zu verlieren

Übergib bei einer Renderfunktion, die ein Ansichtsarray annimmt, tasks.filter(task => !task.done), um nur unerledigte Aufgaben anzuzeigen. Behalte das vollständige Array für spätere Ansichten und Zählungen über die gesamte Liste. Gib Zusammenfassungen klare Bedeutungen: Die Anzahl sichtbarer Aufgaben unterscheidet sich von der Anzahl aller Aufgaben.

sort() ändert das Array, auf dem es aufgerufen wird. Sortiere für die Anzeige eine Kopie mit [...tasks].sort(...) oder verwende tasks.toSorted(...) für eine sortierte Kopie. Gib eine Vergleichsfunktion an: Numerische Werte benötigen (a, b) => a - b, und für Titel eignet sich (a, b) => a.title.localeCompare(b.title). Die Standardsortierung vergleicht Zeichenkettenformen, sodass [100, 25, 3].sort() in dieser Reihenfolge bleibt; numerisches Sortieren ergibt [3, 25, 100].

Ordne IDs zu und parse Daten korrekt

Eine angezeigte dataset.id ist eine Zeichenkette. Wandle sie vor einem strikten Vergleich mit numerischen IDs um, sonst kann find() den Wert undefined zurückgeben, selbst wenn das gesuchte Objekt existiert. JSON-Daten sind anders: JSON.parse() erhält JSON-Zahlen und boolesche Werte mit diesen Typen. Geparste Objekte können dieselbe Renderfunktion durchlaufen wie direkt im Code geschriebene Objekte.

Erhalte bei Bedarf den lokalen Zustand

Ein vollständiger Neuaufbau erstellt neue Elemente. Dabei können der Fokus und in Eingabefelder innerhalb des neu aufgebauten Bereichs eingegebener Text verloren gehen. Aktualisiere bei einer kleinen Zustandsänderung, bei der diese Objekte erhalten bleiben müssen, zuerst die Daten und dann den vorhandenen Eintrag, etwa mit li.classList.toggle("done", task.done). Die Daten müssen die Änderung weiterhin festhalten, damit ein späteres vollständiges Rendern mit der aktuellen Anzeige übereinstimmt.

Gib Ansicht und Zusammenfassung getrennte Eingaben

Eine gefilterte Ansicht kann weiterhin eine Zusammenfassung aller Aufgaben anzeigen:

function renderOpenTasks() {
  const visible = tasks.filter(task => !task.done);
  const nodes = visible.map(task => {
    const li = document.createElement("li");
    li.textContent = task.text;
    return li;
  });
  if (visible.length === 0) {
    const empty = document.createElement("li");
    empty.textContent = "No open tasks";
    nodes.push(empty);
  }
  list.replaceChildren(...nodes);
  const done = tasks.filter(task => task.done).length;
  summary.textContent = `${done} of ${tasks.length} done`;
}

Ein Array mit ausschließlich erledigten Aufgaben zeigt für diese Ansicht die Leermeldung, behält aber jedes Objekt für die Gesamtzahl. Eine Zählung aus visible würde eine andere Frage beantworten und könnte keine erledigten Aufgaben melden, nur weil diese Ansicht sie ausschließt.

Wichtige Erkenntnisse

  • Aktualisiere die Daten und leite dann die Seite aus diesen Daten ab.
  • Ersetze beim Neuaufbau einer Liste alte Kindknoten, um Duplikate zu vermeiden.
  • Filtere und sortiere eine abgeleitete Ansicht und erhalte bei Bedarf das ursprüngliche Array.
  • Gib für numerisches Sortieren eine Vergleichsfunktion an und wandle dataset-IDs vor numerischen Vergleichen um.
  • JSON.parse() erhält numerische und boolesche Datentypen.
  • Aktualisiere gezielt ein Element, wenn ein Neuaufbau benötigte Eingabezustände oder den Fokus verlieren würde.

Document Object Model: Beispiele

6 Interaktive Lektionen

1

Finde dich in einem Seitenbaum zurecht

11 Schritte
Untersuche eine kleine Liste, unterscheide Elemente von Text und verfolge zuverlässige Pfade zu benachbarten Inhalten.
  1. 1
    EinführungBeginne mit einer Seite, die du untersuchen kannst

    Der Browser erstellt Objekte aus HTML. JavaScript arbeitet mit diesem DOM-Baum.

    Verfolge eine Liste mit zwei Einträgen vom Markup bis zu den Knoten und nutze dann Familienbeziehungen, um einen benachbarten Eintrag zu erreichen. Halte die DevTools geöffnet, um die sichtbare Seite mit ihrem Baum zu vergleichen.

  2. 2
    ErklärungSteige über document ein

    Das DOM ist das dynamische Seitenmodell des Browsers. document bietet Zugriff; document.body verweist auf das Body-Element.

    Der Browser stellt diese API bereit. JavaScript ruft sie auf, um die aktuelle Seite zu ändern, ohne sie neu zu laden oder die HTML-Datei des Servers umzuschreiben.

  3. 3
    BeispielBetrachte das Element und seinen Text getrennt

    Betrachte <li>Buy milk</li>. Das <li> wird zu einem Elementknoten und „Buy milk“ zu einem Textknoten als Kindknoten darin.

    Lies nodeType, um sie zu unterscheiden: Das Element hat Typ 1 und sein Textknoten hat Typ 3. Kommentare haben Typ 8 und das Dokument selbst hat Typ 9. „Knoten“ bezeichnet die übergeordnete Gruppe; ein Element ist eine Art von Knoten.

  4. 4
    BeispielZähle, was die Einrückung hinzufügt

    Verwende genau diese Anordnung:

    <ul id="tasks">
      <li>Buy milk</li>
      <li>Call Sam</li>
    </ul>
    

    Die Liste hat zwei Kindelemente. Sie hat außerdem drei Textknoten mit Leerraumzeichen: vor, zwischen und nach diesen Einträgen. Ihre children.length ist daher 2, während childNodes.length gleich 5 ist. Die zusätzlichen Knoten entstehen aus den Zeichen zwischen den Tags.

  5. 5
    HerausforderungBestimme den ersten Knoten

    Welche Art von Knoten ist tasks.firstChild in der eingerückten Liste aus der vorherigen Folie und warum unterscheidet er sich von tasks.firstElementChild?

    ---reveal---

    firstChild ist der Textknoten mit Leerraumzeichen vor dem ersten Eintrag. firstElementChild überspringt diesen Knoten und gibt das erste <li> zurück. Die Einrückung beeinflusst die Knotenfolge, obwohl sie keine weitere sichtbare Aufgabe erstellt.

  6. 6
    TippUntersuche den aktuellen Baum

    Wähle beim ersten Listeneintrag „Untersuchen“. Der Bereich „Elemente“ zeigt das aktuelle DOM. Wenn der Eintrag ausgewählt ist, verweist $0 in der Konsole darauf und console.dir($0) zeigt seine Eigenschaften.

    Der Baum kann vom Parser hinzugefügte Elemente enthalten, etwa ein <tbody> um Tabellenzeilen. Prüfe in diesem Bereich die tatsächliche Verschachtelung, statt anzunehmen, dass sie jeder Tag-Grenze im Quelltext entspricht.

  7. 7
    BeispielGehe zum nächsten Element

    Speichere die Liste als tasks und folge dann einer Elementbeziehung:

    const first = tasks.firstElementChild;
    const second = first.nextElementSibling;
    

    second.textContent ist „Call Sam“. Das Lesen von first.nextSibling erreicht dagegen die Leerraumzeichen zwischen den Einträgen. Wähle die Elementform, wenn du zwischen Seitenelementen navigieren und Textknoten überspringen möchtest.

  8. 8
    ErklärungHalte beim letzten Eintrag sicher an

    Das nextElementSibling des letzten Eintrags ist null. Das direkte Lesen einer Eigenschaft von dieser fehlenden Referenz löst einen TypeError aus.

    second.nextElementSibling?.textContent hält dort an und ergibt undefined, ohne einen Knoten hinzuzufügen oder eine leere Zeichenkette zu liefern.

  9. 9
    VerbindungFinde den umschließenden Eintrag anhand seiner Bedeutung

    Ein verschachteltes span-Element kann seine umschließende Aufgabe mit span.closest("li") finden. Die Suche beginnt beim span-Element selbst und prüft dann nacheinander Vorfahrenknoten, bis ein Treffer gefunden wird.

    span.matches("li") prüft nur das span-Element und gibt in diesem Fall false zurück. Eine Suche nach Vorfahrenknoten ist nützlich, wenn ein zusätzliches umschließendes Element dazu führen könnte, dass eine feste Anzahl von Schritten über Elternknoten zur falschen Stelle führt.

  10. 10
    HerausforderungNavigiere durch ein zusätzliches umschließendes Element

    Jeder Listeneintrag umschließt seinen Text nun mit einem span-Element. Wie kannst du ausgehend vom ersten span-Element den Text des nächsten Eintrags lesen, ohne von Leerraumknoten oder der Anzahl umschließender Elemente innerhalb eines Eintrags abhängig zu sein?

    ---reveal---

    Finde den umschließenden Eintrag und dann sein nächstes Geschwisterelement: span.closest("li").nextElementSibling?.textContent. Der umschließende Eintrag wird über sein Tag gefunden, und die Navigation nur über Geschwisterelemente überspringt die Leerraumzeichen zwischen den Einträgen.

  11. 11
    ZusammenfassungProbiere als Nächstes eine Tabelle

    Untersuche eine Tabelle, deren Quelltext eine Zeile direkt innerhalb von <table> platziert. Finde den tatsächlichen Elternknoten der Zeile.

    Vergleiche die Anzahl ihrer Kindknoten und Kindelemente und erkläre anhand des Bereichs „Elemente“ die vom Parser hinzugefügte Struktur und die Leerraumzeichen.

2

Wähle die gewünschten Elemente aus und aktualisiere sie

12 Schritte
Wähle den Suchbereich, prüfe fehlende Ergebnisse und vermeide Überraschungen bei Schleifen über dynamische Sammlungen.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungWähle eine Suche, bevor du eine Seite änderst
  2. 2
    ErklärungVerwende die passende ID-Syntax für die Methode
  3. 3
    BeispielSuche eine wiederholte Klasse innerhalb ihrer Karte
  4. 4
    TippUnterscheide einen fehlenden Knoten von falscher Syntax
  5. 5
    HerausforderungErkläre ein frühes null-Ergebnis
  6. 6
    BeispielDurchlaufe die zurückgegebenen Elemente
  7. 7
    ErklärungWandle um, wenn du Arraymethoden benötigst
  8. 8
    BeispielVergleiche zwei gespeicherte Sammlungen
  9. 9
    KernaussageBeobachte eine schrumpfende dynamische Sammlung
  10. 10
    HerausforderungWähle den richtigen kombinierten Selektor
  11. 11
    HerausforderungVerbinde einen Suchbereich mit sicherem Durchlaufen
  12. 12
    ZusammenfassungUntersuche deine nächste fehlgeschlagene Suche
3

Aktualisiere ein Profil und lies seine Formularwerte

15 Schritte
Wähle für unterschiedliche Arten von Informationen einfachen Text, Elementeigenschaften, Attribute und dataset-Einträge.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungUnterscheide die Informationen eines Elements
  2. 2
    BeispielLies Text ohne seine Tags
  3. 3
    ErklärungBehandle externe Werte als Zeichen
  4. 4
    HerausforderungErhalte ein vorhandenes Eingabefeld
  5. 5
    VerbindungLies bei Bedarf den gerenderten Text
  6. 6
    BeispielLies eine geschriebene oder eine aufgelöste URL
  7. 7
    ErklärungSetze einen booleschen Wert über das Vorhandensein
  8. 8
    HerausforderungKorrigiere ein deaktiviertes Bedienelement
  9. 9
    BeispielWandle einen Datennamen in einen Eigenschaftsnamen um
  10. 10
    ErklärungLies den aktuellen Feldinhalt
  11. 11
    HerausforderungRechne mit einem Feldwert
  12. 12
    BeispielFinde ein Objekt anhand einer angezeigten ID
  13. 13
    TippGib einem Symbol-Bedienelement einen lesbaren Namen
  14. 14
    HerausforderungVerbinde Datensuche mit sicherer Anzeige
  15. 15
    ZusammenfassungUntersuche ein Feld vor und nach der Bearbeitung
4

Lass das Aussehen einem klaren Zustand folgen

13 Schritte
Schalte Klassen um, berechne Fortschrittsstile und synchronisiere einen Bereich mit seinem barrierefrei mitgeteilten aufgeklappten Zustand.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungLass Daten den sichtbaren Zustand bestimmen
  2. 2
    BeispielErhalte eine Basisklasse beim Hinzufügen eines Zustands
  3. 3
    ErklärungVerwende eine Bedingung für wiederholte Aktualisierungen
  4. 4
    HerausforderungBestimme das Ergebnis zweier wiederholter Aktualisierungen
  5. 5
    BeispielBerechne einen CSS-Prozentwert
  6. 6
    ErklärungLies das Ergebnis der Kaskade
  7. 7
    HerausforderungStelle die Farbe des Stylesheets wieder her
  8. 8
    ErklärungWähle, was ein geschlossener Bereich entfernt
  9. 9
    BeispielStimme einen Bereich und sein Bedienelement aufeinander ab
  10. 10
    TippPrüfe einen Stil, der hidden übersteuert
  11. 11
    HerausforderungUntersuche ein unsichtbares, aber aktives Bedienelement
  12. 12
    HerausforderungKombiniere Klassen mit einem berechneten Wert
  13. 13
    ZusammenfassungPrüfe Zustand und Aussehen getrennt
5

Erstelle Einträge und verfolge ihre Objektreferenzen

12 Schritte
Erstelle und füge neue Inhalte ein, verschiebe einen vorhandenen Eintrag und entferne und klone anschließend, ohne die Identität aus dem Blick zu verlieren.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungErstelle einen Aufgabeneintrag in einzelnen Schritten
  2. 2
    BeispielErstelle einen losgelösten Eintrag
  3. 3
    BeispielFüge den fertigen Eintrag ein
  4. 4
    ErklärungWähle Kind- oder Geschwisterknoten
  5. 5
    BeispielVerschiebe einen bereits vorhandenen Knoten
  6. 6
    HerausforderungErkläre ein Schleifenergebnis mit einem Eintrag
  7. 7
    ErklärungLöse ein Element, ohne eine Referenz zu verlieren
  8. 8
    BeispielErsetze einen Eintrag oder eine ganze Anzeige
  9. 9
    TippKopiere Nachfahrenknoten und prüfe IDs
  10. 10
    HerausforderungBestimme das Ergebnis einer flachen Kopie
  11. 11
    HerausforderungVerschiebe das Original und füge eine Kopie ein
  12. 12
    ZusammenfassungVerfolge Identitäten neben dem Markup
6

Rendere eine Liste aus Daten und aktualisiere sie zuverlässig

17 Schritte
Erstelle wiederholte Einträge, verwende ein Template sicher und halte gefilterte Ansichten und Zusammenfassungen mit den Daten konsistent.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungLass das Array die Anzeige bestimmen
  2. 2
    BeispielSchreibe eine Erstellungsfunktion für ein Buch
  3. 3
    BeispielEntfalte das Array in Knotenargumente
  4. 4
    TippHalte fehlende Daten lesbar
  5. 5
    VerbindungWende das Muster auf Tabellenzeilen an
  6. 6
    HerausforderungFinde heraus, warum die Liste Objekttext zeigt
  7. 7
    BeispielSammle Knoten außerhalb der Seite
  8. 8
    ErklärungHalte wiederholte Struktur in HTML
  9. 9
    BeispielFülle den Klon vor dem Übertragen
  10. 10
    HerausforderungErhalte das wiederverwendbare Template
  11. 11
    ErklärungErsetze die Anzeige anhand aktueller Daten
  12. 12
    BeispielAktualisiere ein Objekt und seine Zusammenfassung
  13. 13
    ErklärungHalte eine sortierte Ansicht getrennt
  14. 14
    HerausforderungErkläre einen Eintrag, der nach dem Löschen wiederkehrt
  15. 15
    KernaussageErhalte den lokalen Eingabezustand
  16. 16
    HerausforderungVerbinde eine Suche mit einer gezielten Aktualisierung
  17. 17
    ZusammenfassungPrüfe das Rendern in drei Zuständen

Document Object Model: Übungsaufgaben

50 Übungsfragen in 5 Sets

Set 1: Lies und ändere eine Seite10 Übungsfragen

Frage 1 von 10

Ein Skript ändert einen Absatz von „Draft“ zu „Ready“. Was zeigt „Seitenquelltext anzeigen“ nach der Änderung für diesen Absatz?
  1. Den aktualisierten DOM-Text „Ready“.
  2. Den ursprünglichen HTML-Text „Draft“.
  3. Beide Texte als benachbarte Textknoten.
  4. Einen leeren Absatz nach der Änderung.
Antwort zeigenAntwort ausblenden
Antwort: B
„Seitenquelltext anzeigen“ zeigt weiterhin „Draft“, weil es das ursprüngliche HTML liest. Der Bereich „Elemente“ zeigt den geänderten DOM-Text „Ready“; eine Skriptänderung schreibt die HTML-Datei auf dem Server nicht um.

Frage 2 von 10

Bei <ul><li>A</li> <li>B</li></ul> enthält eine Variable first den ersten Eintrag. Was gibt first.nextSibling.nodeType zurück?
  1. 1
  2. 8
  3. 9
  4. 3
Antwort zeigenAntwort ausblenden
Antwort: D
Das tatsächliche Leerzeichen zwischen den beiden Listeneinträgen wird zu einem Textknoten, sodass der nächste Geschwisterknoten nodeType 3 hat. Der zweite Eintrag ist ein Element mit nodeType 1, wird aber über nextElementSibling erreicht. Die Knotennavigation schließt Text zwischen Tags ein; die Elementnavigation überspringt ihn.

Frage 3 von 10

Wie kann ein Skript das Element <section id="report"> mit getElementById() auswählen?
  1. document.getElementById("report")
  2. document.getElementById("#report")
  3. document.getElementById("section#report")
  4. document.getElementById("[id=report]")
Antwort zeigenAntwort ausblenden
Antwort: A
Übergib die reine ID „report“ an getElementById(). Die Raute gehört zur CSS-Selektorsyntax; die Übergabe von „#report“ sucht hier nach einer ID, die dieses Zeichen enthält, und verfehlt diesen Abschnitt.

Frage 4 von 10

Fünf Elemente in der Reihenfolge A bis E haben alle die Klasse flag. Der Code speichert const live = box.getElementsByClassName("flag") und führt dann for (let i = 0; i < live.length; i++) { live[i].classList.remove("flag"); } aus. Welche Elemente behalten die Klasse?
  1. C und E.
  2. B, C und D.
  3. B und D.
  4. A, C und E.
Antwort zeigenAntwort ausblenden
Antwort: C
Das Entfernen von A verschiebt B auf Index 0, aber die Schleife geht zu Index 1 weiter und entfernt C. Dann entfernt sie E bei Index 2, bevor die verkürzte Länge die Schleife beendet. B und D bleiben übrig. Würde man die Sammlung als feste Momentaufnahme behandeln, würde man fälschlich erwarten, dass jedes Element seine Klasse verliert.

Frage 5 von 10

Was erscheint nach label.textContent = "<em>Saved</em>"?
  1. Das Wort „Saved“ in einem em-Element.
  2. Ein em-Element ohne Text darin.
  3. Der wörtliche Text „Saved“.
  4. Der wörtliche Text „Saved“ ohne Tags.
Antwort zeigenAntwort ausblenden
Antwort: C
textContent fügt die wörtlichen Zeichen „Saved“ ein. Die Tags werden nicht zu einem Element für Hervorhebung geparst; verwende das Erstellen von Elementen oder das Parsen vertrauenswürdigen HTMLs, wenn eine Struktur beabsichtigt ist.

Frage 6 von 10

Eine Schaltfläche ist deaktiviert. Code führt button.setAttribute("disabled", "false") aus. Welchen Zustand meldet button.disabled?
  1. false
  2. true
  3. "false"
  4. null
Antwort zeigenAntwort ausblenden
Antwort: B
Das Attribut disabled bleibt vorhanden, daher ist button.disabled wahr. Sein Text „false“ kann ein boolesches Attribut nicht ausschalten; entferne es oder setze die boolesche Eigenschaft auf false, um die Schaltfläche zu aktivieren.

Frage 7 von 10

Ein Eingabefeld enthält aktuell „6“. Was ergibt input.value + 2?
  1. "62"
  2. 8
  3. "8"
  4. 62
Antwort zeigenAntwort ausblenden
Antwort: A
Der Feldwert ist die Zeichenkette „6“, daher verkettet + 2 ihn zu „62“. Wandle vor dem Addieren mit Number(input.value) + 2 um, um die Zahl 8 zu erhalten, auch wenn das Feld ein Zahleneingabefeld ist.

Frage 8 von 10

Eine Karte beginnt mit class="card compact". Wie kann Code „selected“ hinzufügen und beide vorhandenen Klassen erhalten?
  1. card.className = "selected"
  2. card.classList.add(".selected")
  3. card.setAttribute("class", "selected")
  4. card.classList.add("selected")
Antwort zeigenAntwort ausblenden
Antwort: D
classList.add("selected") erhält „card“ und „compact“. Eine Zuweisung der gesamten Klassenzeichenkette ersetzt sie, während ein vorangestellter Punkt Teil des hinzugefügten Tokens statt Selektorsyntax würde.

Frage 9 von 10

Eine Liste enthält Elemente mit den Bezeichnungen P, Q, R. Wie ist ihre Reihenfolge nach list.append(list.firstElementChild)?
  1. P, Q, R, P.
  2. Q, R, P.
  3. R, P, Q.
  4. P, R, Q.
Antwort zeigenAntwort ausblenden
Antwort: B
Das Anhängen des vorhandenen ersten Kindknotens verschiebt P an das Ende, sodass Q, R, P bleibt. Derselbe Knoten kann nicht sowohl die alte als auch die neue Position einnehmen, daher hat die Liste weiterhin drei Elemente. Ein viertes P würde einen separaten Knoten benötigen, zum Beispiel einen Klon, statt desselben Objekts erneut einzufügen.

Frage 10 von 10

makeItem() gibt ein neues <li> zurück. Was fügt list.append(records.map(makeItem)) ein, wenn records zwei Einträge hat?
  1. Zwei li-Elemente mit ihrem erstellten Inhalt.
  2. Ein li-Element mit beiden erstellten Elementen.
  3. Text aus den beiden Elementobjekten.
  4. Zwei Kopien der Datensätze als JSON-Text.
Antwort zeigenAntwort ausblenden
Antwort: C
map() gibt ein Array zurück und append() erhält dieses Array als ein Argument. Es wandelt das Array in Text mit den Zeichenkettendarstellungen der Elemente um, statt die Knoten einzufügen. Verwende list.append(...records.map(makeItem)), um jedes Element als separates Argument zu übergeben.
Set 2: Wähle die richtige DOM-Operation10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

HTML enthält <table><tr><td>8</td></tr></table>. Welches direkte Kindelement platziert der Parser normalerweise innerhalb der Tabelle?
  1. Das tr genau wie geschrieben.
  2. Das td aus der Zeile herausgelöst.
  3. Ein tbody, das die Zeile enthält.
  4. Ein div, das die Tabellenzellen umschließt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein klassisches externes Skript im <head> wählt eine später im <body> geschriebene Fußzeile aus und erhält null. Der Selektor ist korrekt. Welches Skriptattribut sorgt für die Ausführung nach dem Parsen des HTML?
  1. defer
  2. async
  3. disabled
  4. hidden
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Eine statische NodeList enthält zwei .note-Elemente. Eines verliert seine Klasse note und ein neues note-Element wird angehängt. Welche Länge hat die gespeicherte NodeList?
  1. 1
  2. 2
  3. 3
  4. 0
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein Element hat data-record-id="38". Wie kann Code diese ID mit strikter Gleichheit mit der Zahl 38 vergleichen?
  1. row.dataset.recordId === 38
  2. Number(row.getAttribute("record-id")) === 38
  3. row.dataset["record-id"] === 38
  4. Number(row.dataset.recordId) === 38
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Stylesheet setzt die Farbe einer Überschrift und die Überschrift hat keine Inline-Farbe. Wie kann Code die angewandte Farbe lesen?
  1. heading.style.color
  2. getComputedStyle(heading).color
  3. heading.getAttribute("color")
  4. heading.dataset.color
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Ein geschlossener Bereich muss seinen Platz im Layout behalten und vor Screenreadern verborgen sein. Welche CSS-Deklaration passt?
  1. visibility: hidden
  2. display: none
  3. opacity: 0
  4. visibility: visible
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Container hat die Einträge A und B. Code speichert seinen ersten Eintrag als a, ruft container.replaceChildren() auf, setzt a.textContent = "C" und führt dann container.append(a) und container.append(a.cloneNode(true)) aus. Was enthält der Container?
  1. Einen Eintrag mit der Anzeige „C“.
  2. Zwei Einträge mit den Anzeigen „A“ und „C“.
  3. Zwei Einträge, die beide „C“ anzeigen.
  4. Drei Einträge mit den Anzeigen „A“, „B“ und „C“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Datensatz hat score: 0. Was zeigt record.score ?? "Pending" bei einer Zuweisung an textContent an?
  1. „Pending“
  2. „undefined“
  3. Eine leere Zeichenkette.
  4. „0“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine leere Liste erhält ein Fragment mit drei Einträgen. Code ändert dann den textContent des Fragments zu „Reset“ und hängt dasselbe Fragment erneut an. Was steht in der Liste?
  1. Die drei ursprünglichen Einträge, dann der Text „Reset“.
  2. Nur der Text „Reset“ statt der drei Einträge.
  3. Sechs Einträge, gefolgt vom Text „Reset“.
  4. Die drei Einträge, alle mit der Beschriftung „Reset“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Die Daten lauten [{n: 14}, {n: 3}, {n: 9}]. Eine Ansicht soll sie numerisch aufsteigend anzeigen und dabei die Quellreihenfolge erhalten. Welcher Ausdruck erstellt diese Ansicht?
  1. data.sort((a, b) => a.n - b.n)
  2. [...data].sort((a, b) => a.n - b.n)
  3. [...data].sort((a, b) => b.n - a.n)
  4. [...data].sort((a, b) => String(a.n).localeCompare(String(b.n)))
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 3: Verfolge Knoten, Zustand und Sammlungen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Eine Schaltfläche hat selbst die Klasse entry und liegt innerhalb eines Abschnitts mit derselben Klasse. Was gibt button.closest(".entry") zurück?
  1. Den äußeren Abschnitt.
  2. Den Elternknoten des Abschnitts.
  3. Null, weil beide passen.
  4. Die Schaltfläche selbst.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Eine Box enthält anfangs vier .mark-Elemente. Code speichert eine dynamische Klassensammlung und eine statische NodeList der passenden Elemente. Er entfernt das erste Mitglied der dynamischen Sammlung und dann die Klasse vom neuen ersten Mitglied dieser Sammlung. Welche Längen haben die dynamische und die statische Sammlung am Ende?
  1. Dynamisch 2, statisch 3.
  2. Dynamisch 3, statisch 4.
  3. Dynamisch 2, statisch 4.
  4. Dynamisch 3, statisch 3.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Ein Zähler zeigt „12“ an. Welche Zuweisung bewirkt, dass er „13“ anzeigt?
  1. counter.textContent = Number(counter.textContent) + 1
  2. counter.textContent = counter.textContent + 1
  3. counter.textContent = counter.textContent + "1"
  4. counter.textContent = Number(counter.textContent + 1)
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Auf https://example.com/catalog/ steht ein Link als <a href="/guide">Guide</a>. Was gibt link.getAttribute("href") zurück?
  1. "https://example.com/guide"
  2. "/guide"
  3. "https://example.com/catalog/guide"
  4. "guide"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Eine Zeile beginnt mit class="row done". Code führt row.classList.toggle("done", false) zweimal aus. Welche Klassen bleiben?
  1. Nur „row“.
  2. Sowohl „row“ als auch „done“.
  3. Nur „done“.
  4. Es bleiben keine Klassen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Box hat eine Inline-Breite und eine Inline-Farbe. Wie kann Code nur die Inline-Farbe entfernen, sodass das Stylesheet sie bestimmt?
  1. box.style.cssText = ""
  2. box.removeAttribute("style")
  3. box.style.removeProperty("color")
  4. box.style.color = "inherit"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Abschnitt enthält bereits zwei Absätze. An welcher Position sollte insertAdjacentHTML() eine vertrauenswürdige Notiz als ersten Kindknoten des Abschnitts einfügen?
  1. "beforebegin"
  2. "afterbegin"
  3. "beforeend"
  4. "afterend"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Eintrag mit der ID „entry“ und einem verschachtelten span-Element wird tief geklont. Die ID des Klons wird zu „entry-copy“ geändert, dann wird er angehängt und das Original entfernt. Worauf verweist eine gespeicherte Referenz auf das ursprüngliche span-Element?
  1. Auf das entsprechende span-Element im angehängten Klon.
  2. Auf den neuen Elterncontainer des angehängten Eintrags.
  3. Auf null, weil der ursprüngliche Eintrag entfernt wurde.
  4. Auf das span-Element im losgelösten ursprünglichen Eintrag.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Code hängt template.content direkt an eine Liste an. Warum gibt ein späteres template.content.querySelector(".title") null zurück?
  1. Das Template wurde zu einer HTML-Zeichenkette.
  2. Die Klasse wurde beim Einfügen entfernt.
  3. Der Quellinhalt wurde in die Liste verschoben.
  4. Template-Inhalt weist Klassenselektoren zurück.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Die Aufgaben lauten [{id:31, done:true}, {id:32, done:false}, {id:33, done:false}]. Code entfernt nur Zeile 31 aus dem DOM, markiert Aufgabe 32 im Array als erledigt und baut dann alle Zeilen und die Zusammenfassung vollständig aus diesem Array neu auf. Was wird angezeigt?
  1. Drei Zeilen; „2 of 3 done“.
  2. Zwei Zeilen; „1 of 2 done“.
  3. Drei Zeilen; „1 of 3 done“.
  4. Zwei Zeilen; „2 of 2 done“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 4: Erstelle zuverlässige datenbasierte Anzeigen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Absatz enthält Hello, ein verschachteltes <strong>team</strong> und einen HTML-Kommentar. Ist der Text des strong-Elements ein Geschwisterknoten des Kommentars?
  1. Ja, der Absatz ist sein Elternknoten.
  2. Nein, sein Text ist ein Kindknoten von strong.
  3. Ja, Kommentare sind Geschwisterknoten allen Texts.
  4. Nein, dieser Text ist ein Attribut.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Eine Seite hat eine Seitenleiste und einen Hauptbereich, die jeweils .status enthalten. Eine Variable main enthält den Hauptbereich. Welche Suche findet dessen erstes status-Nachfahrenelement?
  1. document.querySelector(".status")
  2. main.getElementById("status")
  3. main.querySelector(".status")
  4. document.getElementById(".status")
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Code speichert const field = box.querySelector("input"). Ein Nutzer ändert dieses Eingabefeld von „A“ zu „B“. Das Skript führt box.innerHTML += "<span>Done</span>" und dann field.value = "C" aus. Was passiert mit dem sichtbaren Eingabefeld?
  1. Es ist ein ersetztes Eingabefeld; die letzte Zuweisung ändert nur das losgelöste Original.
  2. Es ist das ursprüngliche Eingabefeld und zeigt nun den letzten Wert „C“ an.
  3. Es ist das ersetzte Eingabefeld und die gespeicherte Referenz verweist nun darauf.
  4. Es wird dauerhaft entfernt, weil innerHTML Eingabefelder nicht rekonstruieren kann.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein Eingabefeld beginnt mit value="2". Nachdem der Nutzer es zu 7 geändert hat, liest ein Skript Number(input.getAttribute("value")) + 1. Welche Zahl erhält es?
  1. 8
  2. 21
  3. 71
  4. 3
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Bereich wird mit panel.hidden = true ausgeblendet, aber das CSS enthält .panel { display: grid; } und der Bereich bleibt sichtbar. Sein Bedienelement meldet außerdem weiterhin aria-expanded="true". Was korrigiert beide Zustände für einen geschlossenen Bereich?
  1. Die display-Regel beibehalten und aria-expanded ohne CSS-Änderung auf „false“ setzen.
  2. Die Deckkraft auf null setzen und aria-expanded beim aktuellen Wert belassen.
  3. hidden entfernen und aria-expanded passend zum aktuellen Layout auf „true“ setzen.
  4. [hidden] { display: none !important; } durchsetzen und aria-expanded auf „false“ setzen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Liste beginnt mit A, B, C. Code speichert ihr erstes Element als a, führt list.lastElementChild.before(a) und dann list.prepend(list.lastElementChild) aus. Wie lautet die endgültige Reihenfolge?
  1. B, A, C.
  2. C, B, A.
  3. C, A, B.
  4. A, C, B.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Datensatz hat keine Eigenschaft author. Welche Zuweisung zeigt „Unknown author“ an, ohne den Wert als HTML zu parsen?
  1. cell.textContent = record.author ?? "Unknown author"
  2. cell.textContent = String(record.author)
  3. cell.innerHTML = record.author ?? "Unknown author"
  4. cell.textContent = record.author === null ? "Unknown author" : record.author
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Eine Renderfunktion klont ein Template mit einer Zeile, hängt den Klon an ein Fragment an und versucht erst danach clone.querySelector(".name").textContent = record.name. Warum schlägt das fehl?
  1. Ein Fragment kann keine Kindknoten eines anderen Fragments enthalten.
  2. Das tiefe Klonen entfernt Klassen von den geklonten Feldern.
  3. Das Anhängen leerte den Klon, bevor sein Feld gefüllt wurde.
  4. Ein Template-Feld kann vor der Anzeige keinen textContent annehmen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Ein Array hat die IDs 11, 12 und 13. Code entfernt nur das <li> von ID 12 und rendert dann eine gefilterte Ansicht aus dem unveränderten Array. Der Filter behält alle drei Objekte. Was muss sich ändern, damit ID 12 nach jedem späteren vollständigen Rendern gelöscht bleibt?
  1. ID 12 ein zweites Mal aus dem neu gerenderten DOM entfernen.
  2. ID 12 vor dem Rendern aus dem Quellarray entfernen.
  3. Eine statische NodeList behalten, die das gelöschte Element ausschließt.
  4. Das Quellarray vor dem Erstellen der nächsten Ansicht sortieren.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine JSON-Zeichenkette lautet [{"id":24,"done":false}]. Wie unterscheiden sich nach JSON.parse() die Typen von id und done von data-id="24" eines Elements?
  1. Geparste ID ist numerisch; done ist boolesch; dataset-ID ist Text.
  2. Geparste ID ist Text; done ist Text; dataset-ID ist numerisch.
  3. Geparste ID ist numerisch; done ist Text; dataset-ID ist numerisch.
  4. Geparste ID ist Text; done ist boolesch; dataset-ID ist Text.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 5: Finde und behebe Fehler bei DOM-Aktualisierungen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Artikel enthält <div class="card"><div class="body"><span class="label">A</span></div></div>. Ausgehend von der Beschriftung verwendet Code parentElement.parentElement, um die Karte zu finden. Zwischen body und label wird ein neues umschließendes Element eingefügt. Welcher Ersatz bleibt zuverlässig?
  1. label.closest(".card")
  2. label.parentElement.parentElement
  3. label.querySelector(".card")
  4. label.nextElementSibling?.parentElement
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Für eine leere Liste wird die Momentaufnahme snap = list.querySelectorAll(".new") erstellt. Zwei Elemente mit der Klasse new werden angehängt, dann entfernt eine Schleife über snap die Klasse new. Eine neue Klassensuche wird als dynamische Sammlung gespeichert. Wie groß sind snap.length und die Länge der dynamischen Sammlung?
  1. Momentaufnahme 0, dynamisch 0.
  2. Momentaufnahme 2, dynamisch 0.
  3. Momentaufnahme 2, dynamisch 2.
  4. Momentaufnahme 0, dynamisch 2.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Eine Vorschau zeigt einen von einem Nutzer eingegebenen Kommentar an. Ein Entwickler filtert zuerst <script>-Tags heraus. Welche Aktualisierung erhält das Vorschau-Element und fügt den Kommentar ohne HTML-Parsing als wörtlichen Text ein?
  1. preview.innerHTML = comment
  2. preview.textContent = comment
  3. preview.insertAdjacentHTML("beforeend", comment)
  4. preview.outerHTML = comment
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Wie kann Code ein Label über seine DOM-Eigenschaft mit dem Feld verbinden, dessen ID „contact“ ist?
  1. label.for = "contact"
  2. label.id = "contact"
  3. label.htmlFor = "contact"
  4. label.className = "contact"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Eine Zeile beginnt mit class="row selected". Die Daten besagen, dass selected falsch ist. Code führt row.classList.toggle("selected") und später row.classList.toggle("selected", false) aus. Wie lauten die beiden Rückgabewerte und welche Klassen bleiben am Ende?
  1. false, false; nur row bleibt.
  2. false, true; row und selected bleiben.
  3. true, false; nur row bleibt.
  4. true, true; row und selected bleiben.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Ein Fortschrittsbalken stellt 7 erledigte Datensätze von 20 dar. Welche Zeichenkette setzt seine prozentuale Breite korrekt?
  1. "0.35%"
  2. "35px"
  3. "35%"
  4. "7%"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Bereich ist anfangs ausgeblendet und seine Schaltfläche meldet für aria-expanded „false“. Zweimal speichert Code const open = panel.hidden, setzt panel.hidden = !open und schreibt String(open) in aria-expanded. Wie lauten die endgültigen Zustände?
  1. hidden false; aria-expanded „true“.
  2. hidden true; aria-expanded „true“.
  3. hidden false; aria-expanded „false“.
  4. hidden true; aria-expanded „false“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Eintrag <li id="copy-me"><span>Map</span></li> wird mit cloneNode(false) kopiert. Was enthält der losgelöste Klon?
  1. Das li und das span, aber ohne die ID.
  2. Das li und seine ID, ohne span oder Text.
  3. Das li, die ID, das span und den Text „Map“.
  4. Nur einen Textknoten mit „Map“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Für jeden von drei Datensätzen klont Code ein Template mit einem Eintrag tief, füllt dessen Titel und hängt den Klon an ein Sammelfragment an. Dann ruft er list.replaceChildren(fragment) auf. Welche Objekte bleiben gefüllt?
  1. Die Liste und das Sammelfragment; das Quell-Template ist leer.
  2. Nur das Quell-Template; die Liste erhält leere Fragmente.
  3. Die Liste und das Quell-Template; das Sammelfragment ist leer.
  4. Alle drei; jedes behält Kopien derselben Eintragsobjekte.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Daten enthalten {id: 5, done: false}. Die vorhandene Zeile hat data-id="5" und ein fokussiertes Eingabefeld. Code muss den Datensatz als erledigt markieren, dies durch eine Klasse anzeigen und das Eingabeobjekt erhalten. Welche Abfolge passt?
  1. Die dataset-ID umwandeln, das passende Objekt aktualisieren und dann jede Zeile aus den Daten neu aufbauen.
  2. Die dataset-ID direkt mit numerischen IDs vergleichen und dann das gefundene Objekt und die Zeile aktualisieren.
  3. Die Klasse done der vorhandenen Zeile erzwingen, das Objekt unverändert lassen und später alle Zeilen neu aufbauen.
  4. Die dataset-ID umwandeln, das passende Objekt aktualisieren und dann die Klasse done der vorhandenen Zeile erzwingen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe

Schlüsselbegriffe

74 Schlüsselbegriffe, jeweils mit Definition

A

Abgeleitete Ansicht
Eine abgeleitete Ansicht ist ein gefiltertes oder umgeordnetes Array für die Anzeige, während die ursprünglichen Daten für andere Ansichten verfügbar bleiben.
Zeige unerledigte Aufgaben mit tasks.filter(task => !task.done) an, ohne erledigte Aufgaben zu verwerfen.
append()
Die Methode append() fügt Knoten oder einfachen Text nach den vorhandenen Kindknoten eines Containers ein und nimmt mehrere Eingaben in einem Aufruf entgegen.
item.append(title, button) setzt zwei Kindelemente innerhalb eines Eintrags zusammen, bevor dieser in die Seite eingefügt wird.
ARIA-Attribut
Ein ARIA-Attribut liefert Informationen über die Rolle, den Zustand oder den Namen eines Elements für assistive Technologien wie Screenreader.
Das Setzen von aria-label auf „Close dialog“ liefert einen zugänglichen Namen für eine Schaltfläche, die nur ein Symbol zeigt.
aria-expanded
Das Attribut aria-expanded beschreibt assistiven Technologien mit den Zeichenketten „true“ oder „false“, ob ein Bedienelement aufgeklappt oder geschlossen ist.
Wenn sich ein Antwortbereich öffnet, sollte seine steuernde Schaltfläche ebenfalls aria-expanded="true" melden.
Array.from()
Die Methode Array.from() erstellt aus einer Sammlung ein Array und ermöglicht so Arraymethoden und eine Momentaufnahme mit fester Zugehörigkeit.
Array.from(list.children) ermöglicht einer Schleife zum Entfernen, jedes ursprüngliche Kindelement ohne Indexverschiebungen zu besuchen.
Attribut
Ein Attribut ist ein benannter HTML-Wert an einem Element, der mit Methoden wie getAttribute() und setAttribute() gelesen oder geändert werden kann.
Das Attribut href eines Links kann „/help“ enthalten, während seine Eigenschaft eine aufgelöste vollständige URL meldet.

B

Benutzerdefinierte CSS-Eigenschaft
Eine benutzerdefinierte CSS-Eigenschaft ist ein benannter CSS-Wert, der mit zwei Bindestrichen beginnt und auf den Regeln über die Funktion var() verweisen können.
Setze "--accent" über style.setProperty(), um Regeln zu ändern, die auf den Akzentwert verweisen.
Berechneter Stil
Ein berechneter Stil ist ein aufgelöster, schreibgeschützter Stilwert, den der Browser nach Berücksichtigung der anwendbaren CSS-Deklarationen bereitstellt.
getComputedStyle(title).color kann Rot melden, selbst wenn title.style.color leer ist.
Boolesches Attribut
Ein boolesches Attribut steht durch sein Vorhandensein für wahr und durch sein Fehlen für falsch, unabhängig vom Text, der als sein Wert geschrieben wurde.
Eine Schaltfläche bleibt nach setAttribute("disabled", "false") deaktiviert, weil das Attribut existiert.

C

camelCase
camelCase verbindet Wörter, wobei spätere Wortanfänge großgeschrieben werden, wie in backgroundColor.
Die CSS-Eigenschaft background-color wird in JavaScript als style.backgroundColor geschrieben.
checked
Die Eigenschaft checked meldet den aktuellen Auswahlzustand eines Kontrollkästchens als booleschen Wert, unabhängig von seinem anfänglichen Attribut checked.
Nachdem der Nutzer ein zunächst ausgewähltes Kontrollkästchen abgewählt hat, wird seine Eigenschaft checked zu false.
classList
Die Eigenschaft classList stellt die Klassentoken eines Elements und Methoden bereit, um sie einzeln hinzuzufügen, zu entfernen, zu prüfen, umzuschalten oder zu ersetzen.
Das Hinzufügen von „selected“ über classList erhält die vorhandene Klasse „card“ und ihre Grundgestaltung.
className
Die Eigenschaft className ist die gesamte Klassenzeichenkette; eine Zuweisung ersetzt jede Klasse.
Die Zuweisung von „active“ an className einer Karte entfernt ihre frühere Klasse „card“, sofern sie nicht erneut aufgenommen wird.
closest()
Die Methode closest() prüft ein Element und seine Vorfahrenknoten auf den nächsten Selektortreffer.
Ein span-Element innerhalb einer Produktkarte kann mit closest(".product") seine umschließende Karte finden.
createElement()
Die Methode createElement() erstellt anhand eines Tag-Namens ein losgelöstes Element, das später gefüllt und in das Dokument eingefügt werden kann.
document.createElement("li") erstellt einen Listeneintrag, fügt ihn aber noch nicht zur sichtbaren Liste hinzu.
Cross-Site-Scripting
Cross-Site-Scripting ist ein Angriff, bei dem nicht vertrauenswürdiger Inhalt bewirkt, dass von einem Angreifer kontrollierter Code im Browser eines Besuchers ausgeführt wird.
Die Verwendung von textContent für einen eingegebenen Namen verhindert, dass dessen Zeichen zu eingeschleustem Markup werden.
CSS-Einheit
Eine CSS-Einheit gibt einer Länge oder einem anderen Stilwert seine Bedeutung, etwa Pixel für eine absolute Breite oder Prozent für eine relative Breite.
Eine Breite ungleich null benötigt Text wie „180px“; eine reine Zahl wird im Standardmodus ignoriert.
CSS-Selektor
Ein CSS-Selektor ist ein Muster, das anhand von Merkmalen wie Tag, Klasse, ID oder Verschachtelung zu Elementen passt.
Der Selektor "#profile .name" findet Nachfahrenelemente des Profilelements mit der Klasse name.

D

dataset
Die Eigenschaft dataset stellt die Datenattribute eines Elements als Einträge mit Zeichenkettenwerten und in camelCase umgewandelten Namen bereit.
Das Schreiben von row.dataset.recordId = "26" erstellt oder ändert das Attribut data-record-id.
Datenattribut
Ein Datenattribut ist ein benutzerdefiniertes HTML-Attribut, das mit data- beginnt und Informationen für Skripte speichert, ohne sie als Text anzuzeigen.
Eine Zeile mit data-id="26" kann dem Objekt zugeordnet werden, das ihre angezeigten Felder geliefert hat.
defer-Attribut
Das defer-Attribut verzögert ein externes klassisches Skript, bis das Parsen des HTML abgeschlossen ist.
Ein verzögertes Skript im Head kann ein Fußzeilenelement finden, das nahe dem Ende des Body steht.
display: none
Die Deklaration display: none blendet ein Element aus, entfernt seinen Platz im Layout und verbirgt den ausgeblendeten Inhalt vor Screenreadern.
Ein geschlossener Antwortbereich mit dieser Deklaration hinterlässt keinen leeren Block im Seitenlayout.
Document Object Model
Das Document Object Model ist der dynamische Baum aus Seitenobjekten im Browser. Er wird über eine API bereitgestellt und kann von JavaScript gelesen und geändert werden.
Ein Skript aktualisiert über das DOM eine Überschrift, während die Seite im Browser geöffnet bleibt.
DocumentFragment
Ein DocumentFragment ist ein Container außerhalb der Seite, dessen Kindknoten beim Einfügen in das Ziel verschoben werden, sodass das Fragment leer bleibt.
Ein Fragment sammelt mehrere neue Zeilen, bevor deren Kindknoten in den Tabellenkörper übertragen werden.
DOM-Element
Ein DOM-Element ist ein DOM-Knoten, der ein HTML-Tag, seine Attribute und etwaige Kindknoten repräsentiert.
Ein <ul>-Element kann zwei <li>-Kindelemente sowie Textknoten mit Leerraumzeichen enthalten.
Dynamische Sammlung
Eine dynamische Sammlung aktualisiert ihre Zugehörigkeit entsprechend dem aktuellen DOM, sodass Änderungen während einer Schleife ihre Länge und Indizes verändern können.
Das Entfernen einer passenden Klasse beim Vorwärtszählen kann dazu führen, dass eine Schleife das nächste Mitglied der dynamischen Sammlung überspringt.

E

Eigenschaft
Eine Eigenschaft ist ein benannter Wert oder eine Methode am JavaScript-Objekt eines Elements, der oder die mitunter verarbeitete oder typisierte Attributdaten bereitstellt.
Die Eigenschaft disabled gibt einen booleschen Wert zurück, während das Lesen eines Attributs eine Zeichenkette oder null zurückgibt.
Elternknoten
Ein Elternknoten ist der Knoten unmittelbar über einem anderen Knoten im Baum und enthält diesen als Kindknoten.
In <ul><li>Read</li></ul> ist die Liste der unmittelbare Elternknoten des Eintragselements.
Entwicklerwerkzeuge (DevTools)
Die Entwicklerwerkzeuge sind die Werkzeuge des Browsers, mit denen sich das aktuelle DOM, CSS-Regeln, Konsolenausgaben und Elementeigenschaften untersuchen lassen.
Wenn du im Bereich „Elemente“ einen Absatz auswählst, steht er in der Konsole als $0 zur Verfügung.
Erzwungene Klassenumschaltung
Eine erzwungene Klassenumschaltung legt das Vorhandensein einer Klasse anhand eines zweiten booleschen Arguments fest und hält die Klasse so mit einem bekannten Zustand abgestimmt.
row.classList.toggle("done", task.done) hält die Zeile über wiederholte Rendervorgänge hinweg konsistent.

G

Gebündeltes Einfügen
Gebündeltes Einfügen setzt mehrere vorbereitete Knoten durch einen Vorgang in einen Container ein und verwendet dafür ein Fragment oder ein entfaltetes Array aus Knoten.
Erstelle zuerst die Eintragsknoten und übergib sie dann gemeinsam an replaceChildren(...items).
Geschwisterknoten
Ein Geschwisterknoten ist ein Knoten, der im DOM-Baum denselben unmittelbaren Elternknoten wie ein anderer Knoten hat.
Zwei benachbarte Listeneinträge sind Geschwisterelemente, selbst wenn ein Textknoten mit Leerraumzeichen zwischen ihnen liegt.
getElementById()
Die Methode getElementById() findet ein Element anhand seiner wörtlichen ID ohne CSS-Satzzeichen.
document.getElementById("result") sucht nach der ID „result“ ohne vorangestellte Raute.
Gezielte Aktualisierung
Eine gezielte Aktualisierung ändert ein vorhandenes Element passend zu geänderten Daten und erhält dabei das Elementobjekt und seinen lokalen Zustand.
Das Aktualisieren der Klasse done einer einzelnen Zeile kann den Fokus erhalten, der beim Neuaufbau aller Zeilen verloren ginge.

H

hidden
Die Eigenschaft hidden steuert den gewöhnlichen ausgeblendeten Zustand. Das Element bleibt im DOM, während der Standardstil seinen Platz im Layout entfernt.
Setze panel.hidden = false, um einen ausgeblendeten Bereich anzuzeigen, ohne seinen Inhalt neu aufzubauen.
HTMLCollection
Eine HTMLCollection ist eine dynamische indizierte Sammlung von Elementen, die sich aktualisiert, wenn sich die für sie maßgeblichen Elementbeziehungen ändern.
Das Entfernen eines Kindelements ändert die Länge und Indizes der von list.children zurückgegebenen Sammlung.

I

In-place-Sortierung
Eine In-place-Sortierung ordnet das ursprüngliche Array um, sodass vorhandene Referenzen darauf die neue Reihenfolge sehen.
Kopiere mit [...items], bevor du sort() aufrufst, wenn die Quellreihenfolge unverändert bleiben muss.
Inline-Stil
Ein Inline-Stil ist eine CSS-Deklaration im eigenen style-Attribut eines Elements.
Die Zuweisung bar.style.width = "60%" speichert eine berechnete Fortschrittsbreite direkt am Balken.
innerHTML
Die Eigenschaft innerHTML liest inneres Markup und parst zugewiesenes Markup in neue Kindknoten, die die vorhandenen Kindknoten ersetzen.
Die Zuweisung des vertrauenswürdigen "<strong>Ready</strong>" erstellt ein neues strong-Element innerhalb des Containers.
innerText
Die Eigenschaft innerText liest Text entsprechend dem gerenderten Layout und überspringt ausgeblendete Nachfahrenelemente eines angezeigten Elements.
Der innerText einer sichtbaren Beschriftung lässt eine verschachtelte Notiz aus, die mit display: none gestaltet ist.
insertAdjacentHTML()
Die Methode insertAdjacentHTML() parst vertrauenswürdiges Markup an einer benannten Position neben oder innerhalb eines Elements und erhält vorhandene Kindknoten.
Die Position „beforeend“ fügt Markup innerhalb eines Containers nach seinem aktuellen letzten Kindknoten hinzu.
insertBefore()
Die Methode insertBefore() fügt einen Knoten vor einem angegebenen Kindknoten eines Elternknotens ein oder am Ende, wenn diese Referenz null ist.
list.insertBefore(newItem, list.firstElementChild) setzt den Eintrag vor das erste Kindelement.

K

Kindknoten
Ein Kindknoten ist ein Knoten unmittelbar innerhalb eines anderen Knotens, ohne dazwischenliegenden Elternknoten.
Der Text innerhalb eines verschachtelten span-Elements ist ein Nachfahrenknoten des Listeneintrags, aber der direkte Kindknoten des span-Elements.
Klassentoken
Ein Klassentoken ist ein einzelner Klassenname, der im Klassenattribut durch Leerraumzeichen von anderen Namen getrennt ist.
Übergib „large“ und „red“ getrennt an classList.add(), damit keines der Token ein Leerzeichen enthält.
Knoten
Ein Knoten ist ein einzelnes Objekt im DOM-Baum, zum Beispiel ein Element, Text, ein Kommentar oder das Dokument.
Das Absatzelement und der darin enthaltene Text nehmen separate Knoten im Seitenbaum ein.

L

Leerzustand
Ein Leerzustand teilt Nutzern mit, dass keine Dateneinträge zur Anzeige vorhanden sind.
Eine Leseliste ohne Bücher kann anstelle ihrer früheren Einträge „Noch keine Bücher“ anzeigen.
Losgelöster Knoten
Ein losgelöster Knoten ist ein Knoten außerhalb des Dokumentbaums, der im Speicher weiter existieren kann, solange ein Skript eine Referenz darauf hält.
Ein entfernter Eintrag kann über die Variable, die weiterhin auf sein Objekt verweist, erneut angehängt werden.

N

NodeList
Eine NodeList ist eine indizierte DOM-Sammlung mit einer Länge; die von querySelectorAll() zurückgegebene NodeList enthält passende Elemente.
Wandle die ausgewählten Absätze mit Array.from() um, bevor du die Arraymethode map() verwendest.
null
null ist der ausdrückliche Wert für ein fehlendes Ergebnis, den Einzelelementsuchen und Baumeigenschaften zurückgeben, wenn kein passendes Objekt existiert.
Prüfe eine fehlende Bannerreferenz, bevor du ihren Text setzt, denn das Lesen von null löst einen Fehler aus.
Nullish-Coalescing-Operator
Der Nullish-Coalescing-Operator wählt mit ?? nur dann einen Ersatzwert, wenn der linke Wert null oder undefined ist, und lässt andere Werte unverändert.
book.author ?? "Unknown author" liefert lesbaren Text, wenn der optionale Autor fehlt.

O

opacity: 0
Die Deklaration opacity: 0 macht ein Element transparent und erhält dabei seinen Platz im Layout, seine Interaktion und seine Zugänglichkeit für Screenreader.
Eine unsichtbare Schaltfläche kann weiterhin auf Klicks reagieren, wenn nur ihre Deckkraft geändert wurde.
outerHTML
Die Eigenschaft outerHTML enthält das eigene Markup eines Elements; eine Zuweisung ersetzt das Element selbst durch neu geparste Knoten.
Nach dem Ersetzen verweist eine Variable, die den ursprünglichen Absatz enthält, weiterhin auf das losgelöste Objekt.

P

Parsen
Beim Parsen wird das vom Browser gelesene HTML-Markup in einen strukturierten Dokumentbaum umgewandelt.
Beim Parsen von Zeilen direkt innerhalb einer Tabelle kann der Browser ein <tbody>-Element einfügen.
prepend()
Die Methode prepend() fügt Knoten oder einfachen Text vor den vorhandenen Kindknoten eines Containers ein und verschiebt Knoten, die bereits an anderer Stelle existieren.
Das Voranstellen des letzten Elements einer Liste verschiebt dasselbe Objekt an die erste Position, ohne es zu kopieren.

Q

querySelector()
Die Methode querySelector() gibt das erste Element innerhalb ihres Suchbereichs zurück, das zu einem CSS-Selektor passt, oder null, wenn keines passt.
Die Suche innerhalb einer Karte verhindert, dass eine wiederholte Klasse .name an anderer Stelle zum Ergebnis wird.

R

Renderfunktion
Eine Renderfunktion erstellt oder aktualisiert das sichtbare DOM aus aktuellen Daten und kann nach einer Änderung dieser Daten erneut aufgerufen werden.
Der Aufruf der Funktion nach dem Markieren einer Aufgabe als erledigt aktualisiert sowohl die Klasse der Aufgabe als auch eine angezeigte Anzahl erledigter Aufgaben.
Rendern
Rendern ist das Erstellen oder Aktualisieren von DOM-Inhalt aus Daten, sodass die sichtbare Seite die aktuellen Werte darstellt.
Ein Bucharray wird zu einer Liste, indem pro Objekt ein Eintrag mit Titel und Seitenzahl erstellt wird.
replaceChildren()
Die Methode replaceChildren() ersetzt die Kindknoten eines Containers durch übergebene Knoten oder Text oder entfernt sie, wenn keine Eingaben übergeben werden.
Ein vollständiger Rendervorgang nutzt diese Methode, um alte Einträge zu entfernen und die neu erstellte Anzeige einzusetzen.
replaceWith()
Die Methode replaceWith() ersetzt den ausgewählten Knoten selbst an seiner aktuellen Position durch übergebene Knoten oder Text.
Ein Ladeabsatz kann durch eine fertige Liste ersetzt werden, während die umgebende Seite bestehen bleibt.

S

Source of Truth
Die Source of Truth sind die als maßgeblicher Zustand gespeicherten Daten, aus denen die angezeigten Einträge und Zusammenfassungen der Seite abgeleitet werden.
Das Löschen eines Objekts aus einem Aufgabenarray, aus dem eine Liste gerendert wird, verhindert, dass der nächste Rendervorgang seinen Listeneintrag wiederherstellt.
Spread-Syntax
Die Spread-Syntax entfaltet ein iterierbares Objekt in einzelne Werte, sodass ein Array aus Knoten als einzelne Methodenargumente übergeben werden kann.
list.append(...items) fügt jeden erstellten Knoten statt der Zeichenkettendarstellung des Arrays ein.
Statische Sammlung
Eine statische Sammlung behält die Zugehörigkeit, die sie bei ihrer Erstellung hatte, selbst wenn später passende Elemente zur Seite hinzugefügt oder von ihr entfernt werden.
Ein gespeichertes Ergebnis von querySelectorAll() enthält keinen vierten Eintrag, der nach der ursprünglichen Suche angehängt wurde.

T

Tabellenkörper
Ein Tabellenkörper ist der Abschnitt <tbody>, der die Datenzeilen einer Tabelle gruppiert.
Eine Renderfunktion hängt jedes neue <tr> an den ausgewählten Tabellenkörper an und füllt seine Felder in <td>-Zellen.
template-Element
Ein template-Element enthält geparstes HTML, das nicht angezeigt wird, und dient als wiederverwendbare Quelle für Kopien einer wiederholten Struktur.
Ein Karten-Template kann für jedes Objekt eines Datenarrays dieselben span-Elemente für Titel und Details liefern.
Template-Inhalt
Der Template-Inhalt ist das separate DocumentFragment unter template.content, das die nicht angezeigte Kindstruktur des Templates enthält.
Eine Dokumentensuche findet kein span-Element für den Titel innerhalb des Templates; suche innerhalb seines Inhalts oder eines Klons.
textContent
Die Eigenschaft textContent liest Text aus Nachfahrenknoten und ersetzt bei einer Zuweisung Kindknoten durch einfachen Text, ohne HTML zu parsen.
Die Zuweisung von „Ready“ zeigt diese Zeichen an und erstellt kein Element für Hervorhebung.
Textknoten
Ein Textknoten enthält Zeichen im DOM, darunter sichtbare Wörter oder Leerraumzeichen zwischen Tags.
Eine eingerückte Liste kann mit einem Textknoten beginnen, der vor ihrem ersten Eintrag einen Zeilenumbruch enthält.
Tiefer Klon
Ein tiefer Klon kopiert einen Knoten, seine Attribute und seinen vollständigen Teilbaum aus Nachfahrenknoten.
Das tiefe Klonen einer gefüllten Karte kopiert ihren Text und ihre verschachtelten span-Elemente sowie ihre ursprüngliche ID.
toFixed()
Die Methode toFixed() gibt eine Zahl als Zeichenkette mit einer festgelegten Anzahl von Dezimalstellen zurück, die sich für eine formatierte Anzeige eignet.
Eine Temperatur von 28,5 wird vor dem Einfügen in eine Zelle mit toFixed(1) zur Zeichenkette „28.5“.
Typumwandlung
Eine Typumwandlung ändert die Darstellung eines Werts, indem sie zum Beispiel numerischen Text aus einem Feld oder Datenattribut in eine Zahl umwandelt.
Number(row.dataset.id) ermöglicht der strikten Gleichheit, die gespeicherten Ziffern mit einer numerischen Objekt-ID zu vergleichen.

V

value
Die Eigenschaft value enthält den aktuellen Wert eines Formularsteuerelements als Zeichenkette; er kann von seinem anfänglichen HTML-Attribut abweichen.
Das Lesen eines Mengenfelds nach der Bearbeitung gibt den aktuell eingegebenen Text zurück, nicht seinen Anfangswert.
Vergleichsfunktion
Eine Vergleichsfunktion gibt durch ihren Rückgabewert vor, wie zwei Werte beim Sortieren anzuordnen sind.
Die Vergleichsfunktion (a, b) => a - b ordnet numerische Werte von klein nach groß.
visibility: hidden
Die Deklaration visibility: hidden blendet ein Element aus, erhält dabei seinen Platz im Layout und verbirgt es vor Screenreadern.
Eine unsichtbare Statusbox kann ihren üblichen Platz reservieren, damit sich der umgebende Inhalt nicht verschiebt.
Vorfahrenknoten
Ein Vorfahrenknoten ist ein Elternknoten oder weiter entfernter umschließender Knoten auf dem Weg zum Dokument.
Eine Liste ist ein Vorfahrenknoten des Texts in einem span-Element, das innerhalb eines ihrer Listeneinträge verschachtelt ist.

Über diese Einheit

Von StudeliFehler melden

Erstelle deine eigenen Lernmaterialien

Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.

Jetzt starten