Signatur
Beschreibung
intersectsNode() stellt fest, ob sich ein Knoten mit einem Range überschneidet. Der Knoten muss dafür nicht vollständig im Bereich liegen: Es genügt, dass irgendein Teil von ihm (auch ein Teil seines Inhalts) zwischen Start- und Endpunkt des Bereichs liegt. Deshalb liefert die Methode auch dann true, wenn der Bereich komplett innerhalb des Knotens liegt, etwa bei einer Markierung mitten in einem Absatz.
Genau genommen macht der Algorithmus Folgendes: Liegt der Knoten in einem anderen Baum (anderes Wurzelelement) als der Bereich, ist das Ergebnis false. Hat der Knoten kein Elternelement (z. B. document selbst), ist das Ergebnis true. Andernfalls wird geprüft, ob die Position direkt vor dem Knoten im Elternelement vor dem Ende des Bereichs liegt und die Position direkt nach dem Knoten hinter dem Anfang des Bereichs liegt.
Typische Einsatzgebiete sind Editoren und Werkzeuge, die mit Textmarkierungen arbeiten. Man kann damit herausfinden, welche Absätze, Listeneinträge oder Tabellenzellen eine Benutzermarkierung (Selection.getRangeAt()) berührt, um sie zu formatieren, zu kopieren oder hervorzuheben.
Wer wissen will, ob ein Knoten vollständig im Bereich liegt, braucht einen anderen Weg, zum Beispiel Selection.containsNode(node, false) oder einen Vergleich mit Range.compareBoundaryPoints() bzw. Range.comparePoint().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $referenceNode Pflicht | Node | Der Knoten, der mit dem Bereich verglichen wird. Das kann jeder beliebige Node sein, also Element, Textknoten, Kommentar oder Dokument. Fehlt das Argument oder ist es kein Node, wird ein TypeError ausgelöst. |
Rückgabewert
true, wenn der Knoten den Bereich schneidet (auch teilweise oder wenn der Bereich im Knoten liegt), sonst false.Beispiele
Grundlegende Prüfung mit einem erzeugten Range
// HTML: <p id="a">Erster</p><p id="b">Zweiter</p><p id="c">Dritter</p>
const a = document.getElementById('a');
const b = document.getElementById('b');
const c = document.getElementById('c');
const range = document.createRange();
// Bereich geht vom Inhalt von #a bis in den Inhalt von #b
range.setStart(a.firstChild, 2);
range.setEnd(b.firstChild, 3);
console.log(range.intersectsNode(a)); // teilweise enthalten
console.log(range.intersectsNode(b)); // teilweise enthalten
console.log(range.intersectsNode(c)); // außerhalb
Von der Markierung berührte Listeneinträge hervorheben
// HTML: <ul id="todo"><li>Einkaufen</li><li>Kochen</li><li>Spülen</li></ul>
const list = document.getElementById('todo');
document.addEventListener('selectionchange', () => {
const selection = document.getSelection();
const items = list.querySelectorAll('li');
if (!selection || selection.rangeCount === 0) {
items.forEach((li) => li.classList.remove('markiert'));
return;
}
const range = selection.getRangeAt(0);
items.forEach((li) => {
li.classList.toggle('markiert', range.intersectsNode(li));
});
});
Zusammengefallener Range innerhalb eines Knotens
const p = document.createElement('p');
p.textContent = 'Hallo Welt';
document.body.append(p);
const range = document.createRange();
// Cursorposition mitten im Text (Start = Ende)
range.setStart(p.firstChild, 5);
range.collapse(true);
console.log(range.collapsed); // true
console.log(range.intersectsNode(p)); // Bereich liegt im Absatz
console.log(range.intersectsNode(document.head)); // anderer Teilbaum
Knoten aus einem anderen Dokument
const range = document.createRange();
range.selectNodeContents(document.body);
const fremdesDoc = document.implementation.createHTMLDocument('Test');
const fremderKnoten = fremdesDoc.createElement('div');
fremdesDoc.body.append(fremderKnoten);
// Andere Wurzel: immer false
console.log(range.intersectsNode(fremderKnoten));
// Wichtig · Fallstricke
- Schneiden heißt nicht Enthaltensein:
truekommt auch dann zurück, wenn der Knoten nur teilweise im Bereich liegt oder den Bereich vollständig umschließt, z. B. bei jedem Vorfahren des markierten Textes,document.bodyeingeschlossen. Wer auf vollständiges Enthaltensein prüfen will, nimmtSelection.containsNode(node, false)oder vergleicht die Grenzpunkte. - Bloßes Berühren zählt nicht: Endet der Bereich genau vor dem Knoten oder beginnt er genau danach (Grenzpunkt im Elternelement bei Index bzw. Index + 1), ist das Ergebnis
false. - Knoten ohne Elternelement: Liegt ein Knoten ohne Elternelement im selben Baum wie der Bereich (z. B.
document), ist das Ergebnis immertrue. Losgelöste Knoten, die zu einem anderen Baum gehören, ergebenfalse. - Anderer Baum: Knoten aus einem anderen Dokument, einem losgelösten Teilbaum oder einem anderen Shadow-Root als der Bereich ergeben
false. StaticRangehat diese Methode nicht. Nur ein echter (lebendiger)Rangebietet sie.- Kompatibilität: Wird von allen aktuellen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Der Internet Explorer kennt die Methode nicht; dort ging man über
compareBoundaryPoints(). - Leistung: Wer die Methode bei
selectionchangefür sehr viele Knoten aufruft, kann spürbare Kosten verursachen. Dann besser die Auswahl der Kandidaten eingrenzen, z. B. mitrange.commonAncestorContainer.