JavaScript/Tutorials/DOM/Was ist das DOM

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Das DOM ist eigentlich eine Schnittstelle zwischen JavaScript und HTML-Dokumenten, der Name Document Object Model bezieht sich auf das zugrundeliegende Objektmodell.

Ein HTML-Dokument besteht ja eigentlich nur aus reinem Text, der erst vom Browser ausgelesen und geparst wird. Die einzelnen Elemente werden so in einer Baumstruktur als Unterobjekte des window-Objekts dargestellt. DOM - Baumstruktur einer Webseite

Dieses Tutorial zeigt, wie Sie mit JavaScript nun beliebige Elemente im Elementbaum ansprechen und diese verändern, entfernen und mit Anwenderereignissen verknüpfen können.

Elementknoten ansprechen

Erinnern Sie sich noch an unser "Hallo Welt"-Beispiel? Die Nachteile einer Textausgabe mittels alert sind vor allem die Speicherbelastung des Browsers sowie die mangelnde Gestaltungsmöglichkeit des Ausgabefensters.

<output id="info"></output>


<script>
  'use strict';
  let text = 'Hallo Welt!';
  
  document.getElementById('info').innerText = text;
  
</script>

Das Script ist nun in eine Webseite eingebunden. Teil dieser Webseite ist ein (noch) leeres output-Element mit der id info. Anstelle der Ausgabe mit alert wird mit document.getElementById das output-Element über seine id info angesprochen und mit innerText mit dem auszugebenden Text gefüllt.
Ein weiterer Vorteil dieser Methode ist die Möglichkeit den Ausgabetext beliebig mit CSS zu gestalten.


Dies war die früher übliche Methode, mit JavaScript auf einzelne Elemente zuzugreifen. Da man nicht genau wusste, welche Elemente später als Zugriffspunkte benötigt würden, wurden sicherheitshalber viele id-Attribute vergeben, die das HTML-Markup (womöglich noch in Verbindung mit präsentationsbezogenen Klassennamen ) unnötig aufblähten.

Empfehlung: Versuchen Sie semantisches Markup zu verwenden.
  • Verwenden Sie die passenden Elemente und nutzen Sie deren browsereigene Funktionalität!
  • Setzen Sie ids und Klassennamen nur sparsam ein.

Da diese Art des Elementzugriffs eigentlich umständlich war, entwickelten Frameworks wie jQuery eine Methode, die den direkten Zugriff auf Elemente über ihren Tag-Namen oder über Klassen und Attribute ermöglichte. Diese querySelector-Methode wurde in natives JavaScript übernommen und wird von allen Browsern verstanden.

Im Folgenden verwenden wir die vielseitigere querySelector()-Methode. Sie benötigt als Parameter einen „normalen“ CSS-Selektor und ist daher vielseitiger als das traditionelle getElementById().

<output></output>

<script>
  'use strict';
  let text = 'Hallo Welt!';
  
  document.querySelector('output').innerText = text;
  
</script>

Das (noch) leere output-Element wird über die querySelector()-Methode angesprochen und mit innerText mit dem auszugebenden Text gefüllt.


Empfehlung: Gegenüber document.getElementById(), das nur Elemente anspricht, die ein eindeutiges, unverwechselbares id-Universalattribut besitzen, sucht die querySelector-Methode nach den im CSS üblichen Selektoren wie Elemente, Klassen und IDs, aber auch ARIA-Attributen, wie wir später sehen werden.
Sie spricht das erste gefundene Element an. Mit QuerySelectorAll könnten Sie alle vorhandenen Vorkommen ansprechen.


Mit diesen Methoden können Sie auf das DOM (und dessen Elementknoten) einer Webseite zugreifen:

  • querySelector: gibt das erste Element zurück, das dem angegebenen CSS-Selektor entspricht
  • querySelectorAll: gibt eine Liste von Elementen zurück, die dem angegebenen CSS-Selektor entsprechen
  • getElementsByClassName: gibt eine Liste von Elementen zurück, die der angegebenen Klasse entsprechen
  • getElementById: gibt das Element zurück, das die angegebene id besitzt.
  • getElementsByTagName: gibt eine Liste von Elementen zurück, die den angegebenen Namen haben.

Textknoten ansprechen

Die meisten Elemente wie Überschriften, Absätze, Links und Buttons enthalten neben möglichen Kind-Elementen noch Textknoten mit dem eigentlichen Inhalt der Webseite.

Im oberen Beispiel wurde dieser Textknoten mit innerText verändert:

innerText
  document.querySelector('#info').innerText = text;


Des Weiteren existiert mit innerHTML eine weitere Methode, mit der Sie nicht nur Text, sondern sogar weitere HTML-Kindelemente einfügen können.

innerHTML
  document.querySelector('#info').innerHTML = '<strong>' + text + '</strong>';
In diesem Beispiel wird die Variable text von zwei Zeichenketten umschlossen, in denen sich das Markup für ein strong-Element befindet. Wenn der Code ausgeführt wird, ändert sich nicht nur der Textknoten, sondern es wird ein strong-Element in den Elementbaum eingefügt.
Beachten Sie: Durch die Verwendung von innerHTML könnten hier auch weitere HTML-Elemente beinhaltet sein. Dies wird jedoch als unsicher angesehen, da so unter Umständen Benutzereingaben mit schädlichen Skripten in die Webesite eingefügt werden können.
Hauptartikel: JavaScript/Tutorials/Cross Site Scripting

mehrere Elemente gleichzeitig ansprechen

Die querySelector()-Methode gibt das erste Element, auf den der Selektor zutrifft, zurück - alle anderen werden ignoriert. Um mehrere Elemente zu selektieren, kann man die querySelectorAll()-Methode verwenden.

Beispiele für gültige Selektoren
document.querySelectorAll('article img')          // alle img-Elemente innerhalb von article     
document.querySelectorAll('h2, h3')               // alle h2 + h3 Überschriften
document.querySelectorAll('input[type="number"]') //alle inputs mit type="number"
document.querySelectorAll('tr:nth-child(odd)')    // alle Tabellenreihen mit ungeradem Index
Beachten Sie, dass der Parameter ein String mit einem gültigen CSS-Selektor sein muss.

Die querySelectorAll()-Methode gibt nun eine statische NodeList zurück. Diese ist trotz aller Ähnlichkeit kein Array, kann aber in aktuellen Browsern mit einer for...of-Schleife durchlaufen werden. Darüber hinaus unterstützen die Browser auch von Arrays bekannte forEach-Methode, auch wenn die DOM-Spezifikation das nicht vorschreibt. Die mit allen Browsern kompatible Lösung ist, eine NodeList mit einer Zählschleife zu durchlaufen:

Nodelist mit einer klassischen Zählschleife durchlaufen
    const elements = document.querySelectorAll('article > .beispiel');
    for (let index = 0; index < elements.length; index++) {
      elements[index].classList.add('geändert');
    }

Einfacher ist es mit einer for...of-Schleife:

NodeList und for...of zum Ändern mehrerer Elemente So sieht's aus
  document.getElementById('changer').addEventListener('click', changeClasses);

  function changeClasses() {
    const elements = document.querySelectorAll('article > .beispiel');

    for (let element of elements)
      element.classList.add('geändert');
    });
  }

Im Beispiel werden bei click auf den Button alle Elemente mit der Klasse .beispiel, die direkte Kindelemente eines <article> sind, ermittelt. Die NodeList mit dem Suchergebnis wird in elements gespeichert. NodeList-Objekte sind iterierbar, deshalb kann man die for...of-Schleife nutzen, um die gefundenen Elemente nacheinander zu verarbeiten. Im Schleifenrumpf erhalten die Suchtreffer mit classList.add eine weitere Klasse geändert.