Signatur
Beschreibung
Die schreibgeschützte Eigenschaft firstChild des Node-Interface liefert den ersten direkten Kindknoten im DOM-Baum. Das Ergebnis ist ein beliebiger Node: ein Element, aber auch ein Textknoten (zum Beispiel reiner Leerraum oder Zeilenumbrüche aus dem HTML-Quelltext), ein Kommentar oder eine Verarbeitungsanweisung.
Genau das ist der häufigste Stolperstein: Wenn im Markup zwischen öffnendem Tag und erstem Element ein Zeilenumbruch steht, gibt firstChild einen #text-Knoten zurück und nicht das erwartete Element. Suchen Sie das erste Element, verwenden Sie stattdessen Element.firstElementChild.
firstChild eignet sich besonders für das Durchlaufen des Baums auf niedriger Ebene (zusammen mit nextSibling), zum Leeren eines Containers in einer Schleife oder zum Einfügen vor dem ersten Knoten per insertBefore(neu, parent.firstChild). Der Aufruf entspricht node.childNodes[0] ?? null, ist aber kürzer und erzeugt keine NodeList.
Rückgabewert
Element, Text, Comment …) oder null, wenn der Knoten keine Kinder hat.Beispiele
Leerraum-Textknoten als erstes Kind
// HTML:
// <ul id="liste">
// <li>Eins</li>
// <li>Zwei</li>
// </ul>
const liste = document.getElementById('liste');
console.log(liste.firstChild.nodeName); // Textknoten (Zeilenumbruch)
console.log(liste.firstElementChild.nodeName); // erstes Element
Container schnell leeren
const container = document.querySelector('#ergebnisse');
// Entfernt alle Kindknoten, auch Text und Kommentare
while (container.firstChild) {
container.removeChild(container.firstChild);
}
console.log(container.firstChild);
Neuen Eintrag am Anfang einfügen
const log = document.querySelector('#log');
const eintrag = document.createElement('p');
eintrag.textContent = `Neu: ${new Date().toLocaleTimeString('de-DE')}`;
// Funktioniert auch bei leerem Container: insertBefore(x, null) hängt hinten an
log.insertBefore(eintrag, log.firstChild);
console.log(log.firstChild === eintrag);
Alle direkten Kinder mit firstChild/nextSibling durchlaufen
const zaehleKnotentypen = (parent) => {
const zaehler = {};
for (let n = parent.firstChild; n !== null; n = n.nextSibling) {
zaehler[n.nodeName] = (zaehler[n.nodeName] ?? 0) + 1;
}
return zaehler;
};
const div = document.createElement('div');
div.innerHTML = 'Text <b>fett</b><!-- Hinweis --><i>kursiv</i>';
console.log(zaehleKnotentypen(div));
// Wichtig · Fallstricke
- Leerraum-Falle: Einrückungen und Zeilenumbrüche im HTML erzeugen Textknoten.
firstChildist deshalb oft ein#text-Knoten. Für ElementefirstElementChildnehmen. - Schreibgeschützt: Eine Zuweisung wie
node.firstChild = xwird still ignoriert (im Strict Mode gibt es einenTypeError). Zum ÄnderninsertBefore(),prepend()oderreplaceChild()verwenden. - Live-Wert: Die Eigenschaft wird bei jedem Zugriff neu ermittelt. Nach DOM-Änderungen zeigt sie sofort den neuen Zustand, darum funktioniert die
while-Schleife zum Leeren. - Bei
documentistfirstChildmeist der<!DOCTYPE>-Knoten (DocumentType) und nicht<html>. Für das Wurzelelementdocument.documentElementverwenden. - Bei
<template>liegen die Kinder intemplate.content, alsotemplate.content.firstChild. - Zum reinen Leeren ist
container.replaceChildren()(modern) odertextContent = ''meist schneller als eine Schleife. - Kompatibilität: Wird seit DOM Level 1 von allen Browsern unterstützt, auch von alten IE-Versionen.