Signatur
Beschreibung
hasChildNodes() prüft, ob ein Knoten überhaupt Kindknoten besitzt. Die Methode liefert dasselbe Ergebnis wie node.firstChild !== null oder node.childNodes.length > 0, macht die Absicht im Code aber deutlicher.
Wichtig: Gezählt werden alle Knotentypen, also nicht nur Elemente, sondern auch Textknoten (auch reiner Leerraum wie Zeilenumbrüche und Einrückungen), Kommentare und Verarbeitungsanweisungen. Ein Element, das im HTML-Quelltext nur einen Zeilenumbruch enthält, hat daher Kindknoten.
Wenn du wissen willst, ob ein Element Kind-Elemente hat, nimm besser element.childElementCount > 0 oder element.firstElementChild !== null. Wenn es um sichtbaren Inhalt geht, eignet sich element.textContent.trim() !== "".
Typische Einsatzfälle sind Schleifen, die einen Container leeren, Prüfungen vor dem Rendern eines Platzhalters („Keine Einträge vorhanden“) und rekursive Durchläufe durch den DOM-Baum.
Rückgabewert
true, wenn der Knoten mindestens einen Kindknoten beliebigen Typs hat, sonst false.Beispiele
Einfache Prüfung auf Kindknoten
const list = document.createElement("ul");
console.log(list.hasChildNodes());
list.append(document.createElement("li"));
console.log(list.hasChildNodes());
Fallstrick: Leerraum-Textknoten zählen mit
const box = document.createElement("div");
box.innerHTML = "\n \n"; // nur Leerraum
console.log(box.hasChildNodes()); // Textknoten vorhanden
console.log(box.childElementCount > 0); // keine Elemente
console.log(box.textContent.trim() !== ""); // kein sichtbarer Text
Container leeren und Platzhalter anzeigen
const clearContainer = (container) => {
while (container.hasChildNodes()) {
container.removeChild(container.firstChild);
}
};
const renderItems = (container, items) => {
clearContainer(container);
for (const text of items) {
const li = document.createElement("li");
li.textContent = text;
container.append(li);
}
if (!container.hasChildNodes()) {
container.textContent = "Keine Einträge vorhanden";
}
};
const ul = document.createElement("ul");
renderItems(ul, []);
console.log(ul.textContent);
renderItems(ul, ["Äpfel", "Birnen"]);
console.log(ul.childNodes.length);
Rekursives Zählen der Blattknoten
const countLeaves = (node) => {
if (!node.hasChildNodes()) return 1;
let sum = 0;
for (const child of node.childNodes) sum += countLeaves(child);
return sum;
};
const div = document.createElement("div");
div.innerHTML = "<p>Hallo <b>Welt</b></p><!-- Hinweis -->";
console.log(countLeaves(div)); // "Hallo ", "Welt", Kommentar
// Wichtig · Fallstricke
- Leerraum und Kommentare: Zeilenumbrüche, Einrückungen und
<!-- -->-Kommentare sind eigene Knoten. Deshalb lieferthasChildNodes()ofttrue, obwohl das Element „leer“ aussieht. Für Elemente nimmchildElementCount, für sichtbaren TexttextContent.trim(). Die CSS-Pseudoklasse:emptybehandelt Leerraum ebenfalls als Inhalt. - Attribute zählen nicht: Attribute sind keine Kindknoten. Für sie gibt es
Element.hasAttributes(). - Shadow DOM: Kindknoten eines angehängten Shadow Roots werden nicht berücksichtigt, nur die Light-DOM-Kinder des Hosts. Bei
<template>liegt der Inhalt intemplate.content, deshalb lieferttemplate.hasChildNodes()in der Regelfalse. - Kein Getter: Es ist eine Methode, also mit Klammern aufrufen.
node.hasChildNodesohne Klammern ist immer truthy, weil es die Funktion selbst ist, und damit ein häufiger Fehler. - Leeren von Containern: Statt einer
while-Schleife geht es moderner mitcontainer.replaceChildren(). - Kompatibilität: Wird von allen Browsern unterstützt, auch von sehr alten. Serverseitig gibt es die Methode in DOM-Implementierungen wie jsdom oder linkedom.