Signatur
Beschreibung
compareDocumentPosition() vergleicht zwei Knoten und gibt eine Zahl zurück, deren Bits die Beziehung beschreiben. Die Bits sind als Konstanten am Node-Interface verfügbar: DOCUMENT_POSITION_DISCONNECTED (1), DOCUMENT_POSITION_PRECEDING (2), DOCUMENT_POSITION_FOLLOWING (4), DOCUMENT_POSITION_CONTAINS (8), DOCUMENT_POSITION_CONTAINED_BY (16) und DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC (32).
Die Perspektive ist immer die von otherNode: a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING bedeutet „b folgt auf a“. CONTAINS heißt „b enthält a“ (b ist Vorfahre), CONTAINED_BY heißt „b liegt in a“ (b ist Nachfahre). Mehrere Bits können gleichzeitig gesetzt sein – ein Vorfahre ist z. B. immer auch PRECEDING (8 + 2 = 10), ein Nachfahre immer FOLLOWING (16 + 4 = 20).
Typische Einsatzfälle sind das Sortieren von Knoten in Dokumentreihenfolge (etwa nach querySelectorAll aus mehreren Quellen), die Prüfung, ob ein Element vor oder nach einem anderen steht (z. B. bei Fokus-Management oder Textauswahl), und das Erkennen, ob ein Knoten überhaupt im selben Baum hängt. Werte prüft man immer mit dem bitweisen UND-Operator &, nie per Gleichheit.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $otherNode Pflicht | Node | Der Knoten, dessen Position relativ zum aufrufenden Knoten ermittelt wird. Muss ein gültiger Node sein, sonst wird ein TypeError geworfen. |
Rückgabewert
Node.DOCUMENT_POSITION_*-Konstanten. 0, wenn otherNode derselbe Knoten ist.Beispiele
Prüfen, ob ein Element nach einem anderen steht
document.body.innerHTML = '<h1 id="titel">Titel</h1><p id="text">Text</p>';
const titel = document.getElementById('titel');
const text = document.getElementById('text');
const pos = titel.compareDocumentPosition(text);
if (pos & Node.DOCUMENT_POSITION_FOLLOWING) {
console.log('Der Absatz steht nach der Überschrift');
}
console.log(pos);
Vorfahre, Nachfahre und getrennte Knoten erkennen
const liste = document.createElement('ul');
const eintrag = document.createElement('li');
liste.append(eintrag);
document.body.append(liste);
console.log(eintrag.compareDocumentPosition(liste)); // liste enthält eintrag
console.log(liste.compareDocumentPosition(eintrag)); // eintrag liegt in liste
const lose = document.createElement('div'); // nicht eingehängt
const r = liste.compareDocumentPosition(lose);
console.log(Boolean(r & Node.DOCUMENT_POSITION_DISCONNECTED));
Knoten in Dokumentreihenfolge sortieren
document.body.innerHTML = '<p id="a">A</p><p id="b">B</p><p id="c">C</p>';
const knoten = ['c', 'a', 'b'].map((id) => document.getElementById(id));
const sortiert = [...knoten].sort((x, y) => {
if (x === y) return 0;
return x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
});
console.log(sortiert.map((el) => el.id).join(', '));
// Wichtig · Fallstricke
- Bitmaske, keine Aufzählung: Nie mit
===gegen eine einzelne Konstante vergleichen – ein Vorfahre liefert z. B.10(CONTAINS | PRECEDING). Immer&verwenden. - Richtung beachten: Das Ergebnis beschreibt
otherNodeaus Sicht des aufrufenden Knotens. Vertauschte Argumente sind ein häufiger Fehler. - Getrennte Knoten: Liegen die Knoten in verschiedenen Bäumen (z. B. nicht eingehängt oder anderes Dokument), wird
DISCONNECTED | IMPLEMENTATION_SPECIFICplusPRECEDINGoderFOLLOWINGgesetzt. Diese Reihenfolge ist zwar innerhalb einer Sitzung konsistent, aber willkürlich – nicht darauf verlassen. - Attribute:
Attr-Knoten werden relativ zu ihrem Besitzerelement eingeordnet; zwei Attribute desselben Elements liefern ebenfallsIMPLEMENTATION_SPECIFIC. - Für die reine Frage „ist Nachfahre?“ ist
Node.contains()lesbarer (und liefert auch für den Knoten selbsttrue). - Wird in allen modernen Browsern unterstützt, auch in jsdom/Node.js-DOM-Implementierungen.