Start · Sprachen · JavaScript · Referenz · Node.contains()

Node.contains()

Methode

Prüft, ob <code>otherNode</code> der Knoten selbst oder ein beliebig tief verschachtelter Nachfahre dieses Knotens ist, und gibt <code>true</code> oder <code>false</code> zurück.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

Node.prototype.contains(otherNode)

Beschreibung

Die Methode contains() des Node-Interfaces gibt einen booleschen Wert zurück. Er ist true, wenn otherNode der Knoten selbst ist, eines seiner direkten Kinder (childNodes), ein Kind dieser Kinder und so weiter. Die Prüfung umfasst also den gesamten Teilbaum und nicht nur die direkten Kinder.

Typischer Einsatz ist die Frage, ob ein Ereignis innerhalb oder außerhalb eines Elements ausgelöst wurde. Das braucht man etwa, um Dropdowns, Modals oder Kontextmenüs bei einem Klick außerhalb zu schließen. Auch bei mouseover/mouseout und focusin/focusout hilft contains() zusammen mit relatedTarget, Übergänge zwischen Kindelementen herauszufiltern.

Wichtig: Ein Knoten „enthält“ sich immer selbst. el.contains(el) ergibt daher true. Wer nur echte Nachfahren prüfen will, muss diesen Fall ausschließen oder compareDocumentPosition() verwenden. Mit document.contains(node) lässt sich außerdem schnell prüfen, ob ein Knoten noch im Dokument hängt. Alternativ gibt es dafür die Eigenschaft isConnected.

Parameter

Name Typ Default Beschreibung
$otherNode Pflicht Node | null Der Knoten, der geprüft werden soll. Das kann jeder Knotentyp sein, also auch Textknoten oder Kommentare. Bei null ist das Ergebnis false.

Rückgabewert

Typ
boolean
Beschreibung
Ein boolescher Wert, der true ist, wenn otherNode im Knoten enthalten ist, sonst false. Wenn der Parameter otherNode null ist, gibt contains() immer false zurück.

Beispiele

Grundlegende Prüfung im DOM-Baum

const liste = document.createElement('ul');
const eintrag = document.createElement('li');
const text = document.createTextNode('Hallo');
eintrag.append(text);
liste.append(eintrag);

console.log(liste.contains(eintrag)); // direktes Kind
console.log(liste.contains(text));    // Enkel (Textknoten)
console.log(liste.contains(liste));   // der Knoten selbst
console.log(eintrag.contains(liste)); // Elternknoten ist kein Nachfahre
console.log(liste.contains(null));
true true true false false

Dropdown bei Klick außerhalb schließen

const dropdown = document.querySelector('#menu');

const onDocumentClick = (event) => {
  // Klick innerhalb des Menüs → nichts tun
  if (dropdown.contains(event.target)) return;
  dropdown.hidden = true;
  document.removeEventListener('click', onDocumentClick);
};

document.querySelector('#menu-button').addEventListener('click', (event) => {
  event.stopPropagation();
  dropdown.hidden = false;
  document.addEventListener('click', onDocumentClick);
});

Echtes Verlassen eines Containers mit relatedTarget erkennen

const karte = document.querySelector('.karte');

karte.addEventListener('mouseout', (event) => {
  // Wechsel auf ein Kindelement ignorieren
  if (karte.contains(event.relatedTarget)) return;
  karte.classList.remove('aktiv');
  console.log('Maus hat die Karte verlassen');
});
Maus hat die Karte verlassen

Prüfen, ob ein Element noch im Dokument ist

const hinweis = document.createElement('p');
console.log(document.contains(hinweis)); // noch nicht eingefügt

document.body.append(hinweis);
console.log(document.contains(hinweis));

hinweis.remove();
console.log(document.contains(hinweis), hinweis.isConnected);
false true false false

// Wichtig · Fallstricke

  • Selbst-Einschluss: node.contains(node) liefert true. Für „nur echte Nachfahren“ zusätzlich node !== other prüfen.
  • Shadow DOM: contains() geht nicht über Shadow-Grenzen hinweg. Ein Element im Shadow Root einer Web-Komponente gilt für den Host und für document nicht als Nachfahre. Bei Ereignissen, die aus Komponenten kommen, ist deshalb event.composedPath().includes(el) oft die bessere Wahl.
  • relatedTarget kann null sein, etwa wenn die Maus das Fenster verlässt. contains(null) gibt dann einfach false zurück, einen Fehler gibt es nicht.
  • Wird ein Argument übergeben, das kein Node und nicht null ist, wird ein TypeError geworfen.
  • Browser-Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt. Ältere Internet-Explorer-Versionen boten sie nur für Elemente an, nicht für document und nicht für Textknoten als Argument.
  • Für die genaue Lagebeziehung (davor, danach, Vorfahre) eignet sich compareDocumentPosition().