Skip to content

DOM traversals

Wir können im DOM jedes einzelne Element mit document.querySelector auswählen. Wir können aber auch ein einziges Element auswählen und von diesem Element ausgehend alle anderen Elemente im DOM wählen. Das ist effizienter als JavaScript für jedes einzelne Element von neuem das DOM durchkämmen zu lassen.

Wir können von einem Element aus in drei Richtungen gehen:

  • nach unten
  • seitwärts
  • nach oben

Wir können auf drei verschiedenen Wegen nach unten wandern:

  • querySelector oder querySelectorAll
  • children
  • firstElementchild

Um von einem spezifischen Element aus nach unten zu suchen, können wir element.querySelector verwenden. Wir suchen – ausgehend vom Haus, nicht von draußen – einen bestimmten Raum im Haus. Nicht vergessen, querySelectorAll gibt eine NodeList zurück.

<ul class="list">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
</ul>
const list = document.querySelector('.list');
// <ul class="list">
const listItems = list.querySelectorAll('li');
// NodeList(5) [li, li, li, li, li]

Mit der Eigenschaft children können wir direkte Nachfahren (also in einem Element verschachtelte Elemente/nested elements) selektieren. children gibt eine HTML-Collection zurück, die sich aktualisiert, wenn Kindelemente geändert werden (ist also eine live collection).

const list = document.querySelector('.list');
// <ul class="list">
const listItems = list.children;
// HTMLCollection { 0: li, 1: li, 2: li, 3: li, 4: li, 5: li, length: 5}

Sowohl die NodeList, die wir mit querySelectorAll erhalten, als auch die HTML-Collection als Ergebnis von children sind zwar Listen und keine Arrays, aber die Elemente beider Listen verfügen über einen Index und somit können spezifische Kindelemente mit der bracket notation ausgewählt werden.

// über querySelectorAll und die NodeList:
const list = document.querySelector('.list');
const listItems = list.querySelectorAll('li');
const firstListItem = listItems[0];
// über children und die HTML-Collection:
const list = document.querySelector('.list');
const listItems = list.children;
const secondListItem = listItems[1];

Wir können das erste oder letzte Element einer Liste auch mit firstElementChild bzw. lastElementChild selektieren. Bitte nicht mit firstChild verwechseln (wo war das nochmal? – das müsste jedenfalls einen Knoten zurückgeben, kein Element)!

const list = document.querySelector('.list');
const firstListItem = list.firstElementChild;
const lastListItem = list.lastElementChild;

Nach oben kommen wir auf zwei verschiedenen Wegen:

  • parentElement
  • closest

parentElement ist eine Eigenschaft, die das Elternelement selektiert. Das Elternelement ist das Element, das das aktuelle Element einschließt.
In der Liste unten ist <ul class="list"> das Elternelement aller <li>, und jedes <li> ist seinerseits wieder das Elternelement des jeweiligen <a>.

<ul class="list">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
</ul>
const firstListItem = document.querySelector('li');
const list = firstListItem.parentElement;
// <ul class="list"> ... </ul>

Während sich parentElement gut dazu eignet, das direkte Elternelement zu selektieren, findet closest ein Element, das mehrere Ebenen über dem aktuellen Element steht (das aktuelle Element muss trotzdem ein Nachfahre sein, closest kann kein Geschwisterelement des Vorfahren selektieren).
closest findet also den nächsten Vorfahren, der mit einem bestimmten Selektor übereinstimmt.
Wichtig: closest startet immer beim aktuellen Element! Wenn der Selektor zufällig passt, kann auch das aktuelle Element selbst selektiert werden.
Der Selektor wird wie bei document.querySelector geschrieben.

<ul class="list">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
</ul>
const closestAncestor = Element.closest(selector);
const firstLink = document.querySelector('a');
const list = firstLink.closest('.list');
// <ul class="list"> ... </ul>

Es gibt dei Möglichkeiten, den DOM seitwärts zu durchwandern:

  • nextElementSibling
  • previousElementSibling
  • eine Kombination von parentElement, children und index

nextElementSibling selektiert – wie der Name schon sagt – das nächste Geschwisterelement, während previousElementSibling in die Gegenrichtung sucht und das vorhergehende Geschwisterelement auswählt.

<ul class="list">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
</ul>
const nextElement = Node.nextElementSibling
const list = document.querySelector('.list');
// nextElementSibling
const firstListItem = list.firstElementChild;
const secondListItem = firstListItem.nextElementSibling;
// previousElementSibling
const listItems = list.children;
const fourthListItem = listItems[3];
const thirdListItem = fourthListItem.previousElementSibling;

Combining parentElement, children and index

Section titled “Combining parentElement, children and index”

Eine Kombination von parentElement, children und index lässt uns kreuz und quer durch das DOM gehen.
Wir wollen, ausgehend vom ersten Listenelement, das vierte Listenelement selektieren: Dazu gehen wir nach oben zu parentElement, machen dann eine HTML-Collection mit children und wählen aus dieser Liste das vierte Element aus.

const firstItem = document.querySelector('li');
const list = firstItem.parentElement;
const allItems = list.children;
const fourthItem = allItems[3];
// das geht auch übersichtlich in einem Schritt:
const fourthItem = firstItem.parentElement.children[3];