Start · Sprachen · JavaScript · Referenz · Range.intersectsNode()

Range.intersectsNode()

Methode

Prüft, ob ein Knoten den <code>Range</code> schneidet, also ob er ganz oder teilweise innerhalb der Grenzen des Bereichs liegt, und gibt <code>true</code> oder <code>false</code> zurück.

seit JavaScript DOM Living Standard – Baseline: alle modernen Brow Kategorie: webapi

Signatur

Range.prototype.intersectsNode(referenceNode)

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

Typ
boolean
Beschreibung
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
true true false

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
true true false

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));
false

// Wichtig · Fallstricke

  • Schneiden heißt nicht Enthaltensein: true kommt 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.body eingeschlossen. Wer auf vollständiges Enthaltensein prüfen will, nimmt Selection.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 immer true. Losgelöste Knoten, die zu einem anderen Baum gehören, ergeben false.
  • Anderer Baum: Knoten aus einem anderen Dokument, einem losgelösten Teilbaum oder einem anderen Shadow-Root als der Bereich ergeben false.
  • StaticRange hat diese Methode nicht. Nur ein echter (lebendiger) Range bietet 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 selectionchange für sehr viele Knoten aufruft, kann spürbare Kosten verursachen. Dann besser die Auswahl der Kandidaten eingrenzen, z. B. mit range.commonAncestorContainer.