Start · Sprachen · JavaScript · Referenz · Selection.modify()

Selection.modify()

Methode

Verschiebt den Cursor oder erweitert die aktuelle Auswahl anhand einfacher Textbefehle wie Zeichen, Wort, Zeile oder Absatz.

seit JavaScript Nicht standardisiert; unterstützt in Chrome, Edge, Kategorie: webapi

Signatur

Selection.prototype.modify(alter, direction, granularity)

Beschreibung

Selection.modify() ändert die aktuelle Auswahl bzw. die Cursorposition (Caret) so, wie es sonst Tastaturbefehle tun. Beispiele sind Shift+→ (ein Zeichen weiter auswählen) oder Strg+← (ein Wort zurückspringen). Welche Aktion ausgeführt wird, bestimmen drei Zeichenketten: Was passiert ("move" oder "extend"), in welche Richtung und um welche Einheit.

Die Methode ist besonders nützlich in eigenen Editoren auf Basis von contenteditable, für eigene Tastenkürzel oder um eine Auswahl auf ganze Wörter bzw. Zeilen auszudehnen. Das manuelle Rechnen mit Range-Offsets ist in solchen Fällen oft sehr umständlich, weil Wort- und Zeilengrenzen vom Layout und von der Sprache abhängen. modify() überlässt diese Arbeit der Layout-Engine des Browsers.

Bei "move" wird die Auswahl auf einen Cursor ohne Ausdehnung reduziert und dieser verschoben. Bei "extend" bleibt der Ankerpunkt (anchorNode/anchorOffset) erhalten, und nur der Fokuspunkt (focusNode/focusOffset) wird verschoben. Die Richtungen "forward"/"backward" beachten die Schreibrichtung des Textes. "left"/"right" beziehen sich dagegen auf die sichtbare Richtung auf dem Bildschirm.

Parameter

Name Typ Default Beschreibung
$alter Pflicht "move" | "extend" "move" verschiebt den Cursor und hebt eine bestehende Auswahl auf. "extend" vergrößert oder verkleinert die Auswahl, indem nur der Fokuspunkt verschoben wird.
$direction Pflicht "forward" | "backward" | "left" | "right" Richtung der Änderung. "forward"/"backward" folgen der logischen Schreibrichtung (wichtig bei RTL-Text), "left"/"right" der sichtbaren Richtung.
$granularity Pflicht "character" | "word" | "sentence" | "line" | "paragraph" | "lineboundary" | "sentenceboundary" | "paragraphboundary" | "documentboundary" Einheit, um die verschoben wird. Die …boundary-Werte springen bis zum Anfang bzw. Ende der jeweiligen Einheit, etwa "lineboundary" wie die Tasten Pos1/Ende. Wie gut die einzelnen Werte unterstützt werden, ist von Browser zu Browser verschieden.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Die Methode verändert das Selection-Objekt direkt.

Beispiele

Auswahl auf das ganze Wort unter dem Cursor ausdehnen

// Markiert das Wort, in dem der Cursor gerade steht
const selectCurrentWord = () => {
  const sel = window.getSelection();
  if (!sel.rangeCount) return;

  sel.collapseToStart();                  // Auswahl auf einen Cursor reduzieren
  sel.modify('move', 'backward', 'word'); // zum Wortanfang springen
  sel.modify('extend', 'forward', 'word'); // bis zum Wortende markieren

  console.log(`Ausgewählt: "${sel.toString().trim()}"`);
};

document.addEventListener('dblclick', selectCurrentWord);
Ausgewählt: "Beispiel"

Eigene Tastenkürzel in einem contenteditable-Editor

const editor = document.querySelector('[contenteditable]');

editor.addEventListener('keydown', (event) => {
  if (!event.altKey) return;
  const sel = window.getSelection();

  // Alt+Shift+L: bis zum Zeilenende markieren
  if (event.shiftKey && event.key.toLowerCase() === 'l') {
    event.preventDefault();
    sel.modify('extend', 'forward', 'lineboundary');
  }

  // Alt+J: Cursor ein Wort weiter nach rechts (sichtbare Richtung)
  if (!event.shiftKey && event.key.toLowerCase() === 'j') {
    event.preventDefault();
    sel.modify('move', 'right', 'word');
  }
});

Ganze Zeile auswählen und Anker/Fokus prüfen

const selectLine = () => {
  const sel = window.getSelection();
  if (!sel.rangeCount) return;

  sel.modify('move', 'backward', 'lineboundary');  // an den Zeilenanfang
  sel.modify('extend', 'forward', 'lineboundary'); // bis zum Zeilenende

  console.log('Anker:', sel.anchorOffset, 'Fokus:', sel.focusOffset);
  console.log('Zeile:', sel.toString());
};

document.querySelector('#select-line').addEventListener('click', selectLine);
Anker: 0 Fokus: 42 Zeile: Dies ist die erste sichtbare Zeile im Absatz.

Funktionsprüfung mit Rückfallebene

const moveCaretToEnd = (element) => {
  const sel = window.getSelection();
  if (typeof sel.modify === 'function') {
    element.focus();
    sel.modify('move', 'forward', 'documentboundary');
  } else {
    // Rückfallebene über die Range-API
    const range = document.createRange();
    range.selectNodeContents(element);
    range.collapse(false);
    sel.removeAllRanges();
    sel.addRange(range);
  }
};

moveCaretToEnd(document.querySelector('#notiz'));

// Wichtig · Fallstricke

  • Nicht standardisiert: modify() steht in keiner Spezifikation (weder W3C noch WHATWG), wird aber von allen großen Browsern unterstützt. Das Verhalten kann sich trotzdem im Detail unterscheiden, etwa bei Wortgrenzen, Satzzeichen, Leerzeichen am Wortende oder bei "sentence"/"paragraph". Kritische Abläufe solltest du deshalb in allen Zielbrowsern testen.
  • Firefox: "lineboundary" und einige andere …boundary-Werte werden erst seit Firefox 102 unterstützt. Nicht unterstützte Werte werden je nach Browser still ignoriert.
  • Kein Effekt ohne Auswahl: Wenn rangeCount gleich 0 ist, passiert nichts. Prüfe also vorher, ob eine Auswahl existiert, oder setze eine mit addRange()/collapse().
  • Formularfelder: In <input> und <textarea> wirkt die Methode nicht zuverlässig, weil deren Inhalt nicht Teil der Dokument-Auswahl ist. Nutze dort setSelectionRange() sowie selectionStart/selectionEnd.
  • Layoutabhängig: "line" und "lineboundary" hängen vom gerenderten Zeilenumbruch ab. Bei ausgeblendeten Elementen (display: none) oder vor dem ersten Rendern ist das Ergebnis unzuverlässig.
  • Kein selectionchange-Ersatz: Die Änderung löst asynchron ein selectionchange-Ereignis aus. Das kann in Editoren zu Endlosschleifen führen, wenn dein Handler selbst wieder modify() aufruft.