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

Range.isPointInRange()

Methode

Prüft, ob der Punkt aus <code>referenceNode</code> und <code>offset</code> innerhalb des Range liegt, und gibt <code>true</code> oder <code>false</code> zurück.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2015; ni Kategorie: webapi

Signatur

Range.prototype.isPointInRange(referenceNode, offset)

Beschreibung

isPointInRange() prüft, ob ein bestimmter Randpunkt (engl. boundary point) innerhalb eines Range liegt. Der Punkt besteht aus einem Knoten und einem Offset. Bei Textknoten (Text, Comment, CDATASection) zählt der Offset die Zeichen, bei allen anderen Knoten die Kindknoten.

Start- und Endpunkt des Range gehören mit dazu. Liegt der Punkt genau auf startContainer/startOffset oder auf endContainer/endOffset, ist das Ergebnis also true. Liegt der Knoten in einem anderen Dokument oder Baum als der Range, gibt die Methode einfach false zurück und wirft keinen Fehler.

Typische Einsatzfälle:

  • Prüfen, ob eine Cursorposition (etwa aus document.caretPositionFromPoint()) in einer Auswahl liegt
  • Editoren und Markierungswerkzeuge, die wissen müssen, ob ein Klick in einem markierten Bereich war
  • Suchtreffer oder Anmerkungen auf Überschneidungen prüfen

Wenn du wissen willst, ob ein ganzer Knoten den Range berührt, ist intersectsNode() meist passender. Für die genaue Lage vor, in oder hinter dem Range gibt es comparePoint().

Parameter

Name Typ Default Beschreibung
$referenceNode Pflicht Node Knoten, in dem der zu prüfende Punkt liegt.
$offset Pflicht number Position innerhalb von referenceNode: bei Textknoten die Zeichenzahl, sonst der Index des Kindknotens. Muss zwischen 0 und der Länge des Knotens liegen.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Punkt innerhalb des Range liegt (Start und Ende eingeschlossen), sonst false.

Beispiele

Einfacher Test auf Zeichenposition

const p = document.createElement('p');
p.textContent = 'Hallo schöne Welt';
document.body.append(p);

const text = p.firstChild;
const range = document.createRange();
range.setStart(text, 6);  // vor „schöne“
range.setEnd(text, 12);   // nach „schöne“

console.log(range.isPointInRange(text, 3));  // in „Hallo“
console.log(range.isPointInRange(text, 6));  // genau am Start
console.log(range.isPointInRange(text, 12)); // genau am Ende
console.log(range.isPointInRange(text, 15)); // in „Welt“
false true true false

Prüfen, ob ein Klick in der aktuellen Textauswahl liegt

document.addEventListener('mousedown', (event) => {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0 || selection.isCollapsed) return;

  const range = selection.getRangeAt(0);

  // Cursorposition unter dem Mauszeiger ermitteln (mit Fallback)
  let node, offset;
  if (document.caretPositionFromPoint) {
    const pos = document.caretPositionFromPoint(event.clientX, event.clientY);
    if (!pos) return;
    ({ offsetNode: node, offset } = pos);
  } else if (document.caretRangeFromPoint) {
    const r = document.caretRangeFromPoint(event.clientX, event.clientY);
    if (!r) return;
    node = r.startContainer;
    offset = r.startOffset;
  } else {
    return;
  }

  if (range.isPointInRange(node, offset)) {
    console.log('Klick innerhalb der Auswahl – Kontextmenü anzeigen');
  } else {
    console.log('Klick außerhalb der Auswahl');
  }
});
Klick innerhalb der Auswahl – Kontextmenü anzeigen

Punkt mit Kindknoten-Offset und sichere Fehlerbehandlung

const list = document.createElement('ul');
list.innerHTML = '<li>A</li><li>B</li><li>C</li><li>D</li>';
document.body.append(list);

const range = document.createRange();
range.setStart(list, 1); // vor <li>B</li>
range.setEnd(list, 3);   // nach <li>C</li>

const safeCheck = (node, offset) => {
  try {
    return range.isPointInRange(node, offset);
  } catch (err) {
    console.warn(`${err.name}: ungültiger Punkt`);
    return false;
  }
};

console.log(safeCheck(list, 0));  // vor A
console.log(safeCheck(list, 2));  // zwischen B und C
console.log(safeCheck(list, 99)); // Offset zu groß

// Knoten außerhalb des Dokuments: false, kein Fehler
console.log(safeCheck(document.createElement('div'), 0));
false true IndexSizeError: ungültiger Punkt false false

// Wichtig · Fallstricke

  • Ausnahmen: Ist offset größer als die Länge des Knotens, wird eine IndexSizeError-DOMException geworfen. Ist referenceNode ein DocumentType, wird eine InvalidNodeTypeError geworfen. Wenn der Offset von außen kommt, fang diese Fehler mit try…catch ab.
  • Anderer Baum: Knoten aus einem anderen Dokument, aus einem abgetrennten Teilbaum oder aus einem Shadow-DOM mit anderer Wurzel ergeben false und werfen keinen Fehler. Ältere Browser warfen hier teils WrongDocumentError.
  • Grenzen eingeschlossen: Start- und Endpunkt gelten als „im Range“. Auch ein zusammengefallener (collapsed) Range enthält also genau seinen eigenen Punkt.
  • Offset-Bedeutung: Bei Elementknoten ist der Offset ein Kindindex, keine Zeichenposition. Das ist eine häufige Fehlerquelle bei gemischtem Inhalt.
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt (Chrome, Edge, Firefox, Safari), aber nicht vom Internet Explorer. StaticRange hat diese Methode nicht.