Signatur
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
-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
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));
});
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));
// Wichtig · Fallstricke
- Grenzen zählen mit: Punkte genau auf
startContainer/startOffsetoderendContainer/endOffsetergeben0. Bei einem zusammengefallenen Range (collapsed) liefert nur genau dieser eine Punkt0. - Ausnahmen: Liegt der Knoten in einem anderen Dokument oder Baum, wird ein
WrongDocumentErrorausgelöst. Istoffsetgrößer als die Länge des Knotens, folgt einIndexSizeError. Für einenDocumentType-Knoten gibt es einenInvalidNodeTypeError. Im Gegensatz dazu gibtisPointInRange()bei fremden Wurzeln einfachfalsezurück. - Offset-Bedeutung: Bei Elementen ist der Offset ein Index in
childNodesund keine Zeichenposition. Leere Textknoten aus Leerzeichen und Zeilenumbrüchen im HTML verschieben diese Indizes. - Nur Range, nicht StaticRange:
StaticRangehat 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.