Signatur
Beschreibung
Die schreibgeschützte Eigenschaft anchorOffset gibt an, an welcher Stelle innerhalb von anchorNode die Auswahl beginnt, also dort, wo der Nutzer mit dem Markieren angefangen hat. Ist anchorNode ein Text-, CDATASection- oder Comment-Knoten, zählt der Wert die Zeichen (genauer: UTF-16-Codeeinheiten) vor dem Anker. Bei jedem anderen Elementknoten ist es die Anzahl der Kindknoten vor dem Anker.
Wichtig ist der Unterschied zwischen Anker und Fokus: Der Anker ist der feste Startpunkt, der Fokus (focusNode/focusOffset) ist der bewegliche Endpunkt. Markiert der Nutzer von rechts nach links, liegt der Anker hinter dem Fokus. anchorOffset ist deshalb nicht automatisch der kleinere Wert. Brauchst du Anfang und Ende in Dokumentreihenfolge, nimm getRangeAt(0).startOffset und endOffset.
Einsatz findet die Eigenschaft vor allem in Rich-Text-Editoren, bei der Position des Textcursors in contenteditable-Bereichen, bei Markierungs- und Kommentarfunktionen und immer dann, wenn eine Auswahl gespeichert und später mit Selection.setBaseAndExtent() oder collapse() wiederhergestellt werden soll.
Rückgabewert
rangeCount === 0), ist der Wert 0.Beispiele
Anker der aktuellen Auswahl ausgeben
document.addEventListener('selectionchange', () => {
const sel = document.getSelection();
if (!sel || sel.rangeCount === 0) return;
console.log('Anker-Knoten:', sel.anchorNode?.nodeName);
console.log('Anker-Offset:', sel.anchorOffset);
console.log('Fokus-Offset:', sel.focusOffset);
});
Cursorposition in einem contenteditable-Feld ermitteln
// <div id="editor" contenteditable>Hallo Welt</div>
const editor = document.querySelector('#editor');
editor.addEventListener('keyup', () => {
const sel = window.getSelection();
if (sel.isCollapsed && editor.contains(sel.anchorNode)) {
console.log(`Cursor steht bei Zeichen ${sel.anchorOffset}`);
}
});
Markierrichtung erkennen
const isBackward = (sel) => {
if (sel.anchorNode === sel.focusNode) {
return sel.anchorOffset > sel.focusOffset;
}
const pos = sel.anchorNode.compareDocumentPosition(sel.focusNode);
return Boolean(pos & Node.DOCUMENT_POSITION_PRECEDING);
};
document.addEventListener('mouseup', () => {
const sel = document.getSelection();
if (sel.rangeCount) console.log('Rückwärts markiert:', isBackward(sel));
});
Auswahl speichern und wiederherstellen
const sel = document.getSelection();
const saved = {
anchorNode: sel.anchorNode,
anchorOffset: sel.anchorOffset,
focusNode: sel.focusNode,
focusOffset: sel.focusOffset,
};
// ... später, z. B. nachdem ein Button den Fokus bekommen hat
sel.setBaseAndExtent(
saved.anchorNode, saved.anchorOffset,
saved.focusNode, saved.focusOffset
);
// Wichtig · Fallstricke
- Nicht der Anfang: Wurde rückwärts markiert, ist
anchorOffsetgrößer alsfocusOffset. Für Anfang und Ende in DokumentreihenfolgeRange.startOffsetundRange.endOffsetverwenden. - Einheit hängt vom Knotentyp ab: In einem Elementknoten ist der Wert ein Kindknoten-Index und kein Zeichenversatz. Prüfe deshalb zuerst
anchorNode.nodeType. - UTF-16: Emojis und andere Zeichen außerhalb der BMP zählen als zwei Einheiten. Der Offset stimmt dann nicht mit der Anzahl sichtbarer Zeichen überein.
- Formularfelder: In
<input>und<textarea>liefert die Selection-API keine verlässlichen Offsets innerhalb des Feldes. Nutze dortselectionStartundselectionEnd. - Shadow DOM: Liegt die Auswahl in einem Shadow-Tree, können die Werte je nach Browser auf den Host umgebogen werden. Hilfreich sind
getComposedRanges()(neu, noch nicht überall verfügbar) oder in ChromiumshadowRoot.getSelection(). - Schreibgeschützt: Zuweisungen werden stillschweigend ignoriert. Zum Ändern
collapse(),extend()odersetBaseAndExtent()verwenden. - Kompatibilität: wird von allen modernen Browsern seit Langem unterstützt.