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

Range.comparePoint()

Methode

Prüft, ob ein durch Knoten und Offset angegebener Punkt vor (<code>-1</code>), innerhalb (<code>0</code>) oder nach (<code>1</code>) dem Range liegt.

seit JavaScript Baseline: alle modernen Browser (DOM Living Standa Kategorie: webapi

Signatur

Range.prototype.comparePoint(referenceNode, offset)

Beschreibung

Die Methode comparePoint() des Range-Interfaces vergleicht einen Punkt im Dokument mit den Grenzen des Bereichs. Ein Punkt besteht immer aus einem Knoten und einem Offset in diesem Knoten. Bei Textknoten zählt der Offset die Zeichen, bei allen anderen Knoten die Kindknoten.

Die Methode gibt -1 zurück, wenn der Punkt vor dem Start des Bereichs liegt, 1, wenn er hinter dem Ende liegt, und 0, wenn er innerhalb liegt. Die Grenzen selbst zählen dabei mit: Ein Punkt, der genau auf Start oder Ende fällt, ergibt 0.

Typische Anwendungen sind Editoren, Werkzeuge zum Hervorheben von Text und Kommentarfunktionen. Dort muss man häufig prüfen, ob die Cursorposition oder ein bestimmter Knoten in einer Auswahl liegt, zum Beispiel um Formatierungen anzuwenden oder Markierungen zusammenzufassen. Wenn nur ein Ja oder Nein gebraucht wird, reicht die einfachere Methode isPointInRange(). Die feinere Angabe „davor“ oder „danach“ liefert nur comparePoint().

Parameter

Name Typ Default Beschreibung
$referenceNode Pflicht Node Der Knoten, in dem der zu vergleichende Punkt liegt. Er muss im selben Dokument liegen wie der Range.
$offset Pflicht number Position innerhalb von referenceNode. Bei Text-, Comment- und CDATASection-Knoten ist das die Zeichenposition, sonst der Index des Kindknotens. Der Wert darf nicht größer als die Länge des Knotens sein.

Rückgabewert

Typ
number
Beschreibung
-1, wenn der Punkt vor dem Range liegt, 0, wenn er innerhalb liegt (Grenzen eingeschlossen), und 1, wenn er dahinter liegt.

Beispiele

Grundlegender Vergleich innerhalb eines Textknotens

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.comparePoint(text, 2));  // davor
console.log(range.comparePoint(text, 8));  // innerhalb
console.log(range.comparePoint(text, 12)); // genau auf dem Ende
console.log(range.comparePoint(text, 15)); // dahinter
-1 0 0 1

Prüfen, wo ein Element relativ zur Benutzerauswahl liegt

const describePosition = (element) => {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0) return 'keine Auswahl';
  const range = selection.getRangeAt(0);
  // Punkt: das Element als Kind seines Elternknotens
  const parent = element.parentNode;
  const index = Array.prototype.indexOf.call(parent.childNodes, element);
  const result = range.comparePoint(parent, index);
  return { '-1': 'vor der Auswahl', '0': 'in der Auswahl', '1': 'nach der Auswahl' }[result];
};

document.addEventListener('selectionchange', () => {
  const marker = document.querySelector('#marker');
  if (marker) console.log(describePosition(marker));
});
z. B. "in der Auswahl"

Fehlerbehandlung bei fremden Dokumenten und ungültigem Offset

const range = document.createRange();
range.selectNodeContents(document.body);

const foreignDoc = document.implementation.createHTMLDocument('fremd');

const safeCompare = (node, offset) => {
  try {
    return range.comparePoint(node, offset);
  } catch (err) {
    return `${err.name}`;
  }
};

console.log(safeCompare(foreignDoc.body, 0));
console.log(safeCompare(document.body, 9999));
WrongDocumentError IndexSizeError

// Wichtig · Fallstricke

  • Grenzen zählen mit: Punkte genau auf startContainer/startOffset oder endContainer/endOffset ergeben 0. Bei einem zusammengefallenen Range (collapsed) liefert nur genau dieser eine Punkt 0.
  • Ausnahmen: Liegt der Knoten in einem anderen Dokument oder Baum, wird ein WrongDocumentError ausgelöst. Ist offset größer als die Länge des Knotens, folgt ein IndexSizeError. Für einen DocumentType-Knoten gibt es einen InvalidNodeTypeError. Im Gegensatz dazu gibt isPointInRange() bei fremden Wurzeln einfach false zurück.
  • Offset-Bedeutung: Bei Elementen ist der Offset ein Index in childNodes und keine Zeichenposition. Leere Textknoten aus Leerzeichen und Zeilenumbrüchen im HTML verschieben diese Indizes.
  • Nur Range, nicht StaticRange: StaticRange hat diese Methode nicht.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Edge, Firefox, Safari). Der alte Internet Explorer unterstützt die Methode nicht. In Node.js ist sie nur über DOM-Implementierungen wie jsdom verfügbar.