Start · Sprachen · JavaScript · Referenz · Selection.anchorOffset

Selection.anchorOffset

Eigenschaft

Gibt den Versatz des Auswahl-Ankers innerhalb von <code>Selection.anchorNode</code> zurück – in Zeichen bei Textknoten, sonst als Index der Kindknoten.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

Selection.anchorOffset

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

Typ
number
Beschreibung
Eine nicht-negative Ganzzahl: Zeichenversatz bei Text-, CDATA- oder Kommentarknoten, sonst der Index des Kindknotens. Gibt es keine Auswahl (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);
});
Anker-Knoten: #text Anker-Offset: 4 Fokus-Offset: 11

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}`);
  }
});
Cursor steht bei Zeichen 5

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));
});
Rückwärts markiert: true

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 anchorOffset größer als focusOffset. Für Anfang und Ende in Dokumentreihenfolge Range.startOffset und Range.endOffset verwenden.
  • 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 dort selectionStart und selectionEnd.
  • 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 Chromium shadowRoot.getSelection().
  • Schreibgeschützt: Zuweisungen werden stillschweigend ignoriert. Zum Ändern collapse(), extend() oder setBaseAndExtent() verwenden.
  • Kompatibilität: wird von allen modernen Browsern seit Langem unterstützt.