Signatur
Beschreibung
firstChild() ist eine der Navigationsmethoden eines TreeWalker. Sie sucht unterhalb von currentNode den ersten Knoten, der sichtbar ist. Sichtbar heißt: Der Knotentyp passt zur whatToShow-Maske, und der optionale Filter gibt NodeFilter.FILTER_ACCEPT zurück. Wird ein solcher Knoten gefunden, wird er zum neuen currentNode und zurückgegeben.
Wichtig ist das Verhalten bei gefilterten Knoten: Liefert der Filter FILTER_SKIP, wird nur der Knoten selbst übersprungen. Die Suche geht dann in seine Kinder hinein. Deshalb kann firstChild() auch ein Enkel oder ein noch tiefer liegender Nachfahre im DOM sein. Bei FILTER_REJECT wird dagegen der ganze Teilbaum ausgelassen.
Gibt es kein passendes Kind, liefert die Methode null. currentNode bleibt dann unverändert. So lässt sich die Methode gut als Bedingung in Schleifen verwenden. Typisch ist die Kombination mit nextSibling() und parentNode(), um nur die direkten sichtbaren Kinder eines Knotens zu durchlaufen oder einen Baum rekursiv abzuarbeiten.
Rückgabewert
FILTER_SKIP übersprungen werden). Gibt es keins, wird null zurückgegeben und currentNode bleibt unverändert.Beispiele
Erstes Element-Kind einer Liste ermitteln
document.body.innerHTML = `
<ul id="menu">
<li>Start</li>
<li>Produkte</li>
<li>Kontakt</li>
</ul>`;
const menu = document.getElementById('menu');
const walker = document.createTreeWalker(menu, NodeFilter.SHOW_ELEMENT);
// Leerzeichen-Textknoten werden durch SHOW_ELEMENT ignoriert
const first = walker.firstChild();
console.log(first.textContent);
console.log(walker.currentNode === first);
Direkte sichtbare Kinder mit firstChild() und nextSibling() durchlaufen
document.body.innerHTML = `
<section id="box">
<h2>Titel</h2>
<p>Absatz 1</p>
<p>Absatz 2</p>
</section>`;
const box = document.getElementById('box');
const walker = document.createTreeWalker(box, NodeFilter.SHOW_ELEMENT);
const tags = [];
for (let node = walker.firstChild(); node; node = walker.nextSibling()) {
tags.push(node.tagName);
}
console.log(tags.join(', '));
FILTER_SKIP vs. FILTER_REJECT: firstChild() kann tiefer greifen
document.body.innerHTML = `
<div id="root"><div class="wrapper"><span>Inhalt</span></div></div>`;
const root = document.getElementById('root');
const makeWalker = (result) => document.createTreeWalker(
root,
NodeFilter.SHOW_ELEMENT,
(node) => node.classList.contains('wrapper') ? result : NodeFilter.FILTER_ACCEPT
);
// SKIP: der Wrapper wird übersprungen, seine Kinder werden aber durchsucht
console.log(makeWalker(NodeFilter.FILTER_SKIP).firstChild()?.tagName);
// REJECT: der ganze Teilbaum fällt weg
console.log(makeWalker(NodeFilter.FILTER_REJECT).firstChild());
Kein Kind vorhanden: currentNode bleibt unverändert
document.body.innerHTML = '<p id="leer"></p>';
const p = document.getElementById('leer');
const walker = document.createTreeWalker(p, NodeFilter.SHOW_ALL);
console.log(walker.firstChild());
console.log(walker.currentNode === p);
// Wichtig · Fallstricke
- Nicht mit
Node.firstChildverwechseln:Node.firstChildist eine Eigenschaft, die jedes Kind liefert, auch Leerzeichen-Textknoten und Kommentare.TreeWalker.firstChild()ist eine Methode, diewhatToShowund den Filter berücksichtigt und außerdemcurrentNodeverschiebt. - Nebenwirkung: Die Methode ändert den Zustand des Walkers. Wer später wieder von der alten Position aus weiterarbeiten will, speichert
currentNodevorher in einer Variablen oder springt mitparentNode()zurück. - Tiefere Treffer durch
FILTER_SKIP: Der zurückgegebene Knoten muss kein direktes DOM-Kind sein. Wer nur direkte Kinder braucht, sollteFILTER_REJECTverwenden odernode.parentNodeselbst prüfen. - Die Methode verlässt nie den Teilbaum unterhalb von
root. WurdecurrentNodemanuell auf einen Knoten außerhalb vonrootgesetzt, sucht sie trotzdem unterhalb dieses Knotens. - Der Filter wird bei jedem Aufruf erneut ausgeführt. Rechenintensive Filter können deshalb bei großen Bäumen die Leistung spürbar verschlechtern.
- Kompatibilität: Wird von allen modernen Browsern unterstützt, auch seit Langem vom Internet Explorer 9. In Node.js gibt es die Methode nur über DOM-Implementierungen wie jsdom.