Start · Sprachen · JavaScript · Referenz · Document: selectionchange

Document: selectionchange

Ereignis

Wird am <code>Document</code> ausgelöst, sobald sich die aktuelle Textauswahl (<code>Selection</code>) oder die Cursorposition ändert.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2017/201 Kategorie: webapi

Signatur

document.addEventListener("selectionchange", handler)

Beschreibung

Das Ereignis selectionchange gehört zur Selection API. Der Browser löst es am Document aus, wenn sich die aktuelle Selection ändert. Das passiert, wenn Nutzer Text mit Maus oder Tastatur markieren, den Cursor in einem contenteditable-Bereich verschieben oder wenn ein Skript die Auswahl z. B. über Selection.addRange(), collapse() oder removeAllRanges() ändert.

Einen Handler registrieren Sie mit document.addEventListener("selectionchange", handler) oder über die Eigenschaft document.onselectionchange (bzw. GlobalEventHandlers.onselectionchange). Das Ereignis ist ein einfaches Event. Es steigt nicht auf (bubbles: false) und lässt sich nicht abbrechen (cancelable: false). Welche Auswahl gerade gilt, fragen Sie im Handler mit document.getSelection() ab.

Typische Anwendungen sind schwebende Formatierungsleisten in Rich-Text-Editoren, eine „Zitieren“-Schaltfläche für markierten Text, die Anzeige der Cursorposition oder das Speichern und Wiederherstellen einer Auswahl. Weil das Ereignis beim Ziehen mit der Maus sehr oft kommt, sollten Sie aufwendige Arbeit im Handler drosseln (Throttling oder Debouncing).

Für Textfelder (<input>, <textarea>) feuern neuere Browser selectionchange zusätzlich direkt am Element, und dort steigt es auch auf. Die Position lesen Sie dann über selectionStart und selectionEnd aus, denn document.getSelection() liefert den Inhalt von Formularfeldern nicht.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier immer "selectionchange".
$handler Pflicht (event: Event) => void Callback, das bei jeder Änderung der Auswahl aufgerufen wird. Es bekommt ein einfaches Event ohne Angaben zur Auswahl.
$options boolean | AddEventListenerOptions false Optionen wie { passive: true } oder { signal }, mit denen sich der Handler später über einen AbortController entfernen lässt.

Beispiele

Markierten Text live anzeigen (addEventListener)

const anzeige = document.querySelector('#auswahl-info');

const beiAuswahl = () => {
  const selection = document.getSelection();
  const text = selection ? selection.toString().trim() : '';
  anzeige.textContent = text
    ? `Markiert: „${text}“ (${text.length} Zeichen)`
    : 'Keine Auswahl';
};

document.addEventListener('selectionchange', beiAuswahl);
Markiert: „Hallo Welt“ (10 Zeichen)

Handler über die on-Property setzen und wieder entfernen

document.onselectionchange = () => {
  const sel = document.getSelection();
  console.log('Auswahl eingeklappt?', sel.isCollapsed);
};

// Später deaktivieren:
setTimeout(() => {
  document.onselectionchange = null;
  console.log('Listener entfernt');
}, 10000);
Auswahl eingeklappt? false Listener entfernt

Schwebende Werkzeugleiste mit Debouncing und AbortController

const toolbar = document.querySelector('#toolbar');
const editor = document.querySelector('[contenteditable]');
const controller = new AbortController();
let timer;

const positioniereToolbar = () => {
  const sel = document.getSelection();
  if (!sel.rangeCount || sel.isCollapsed || !editor.contains(sel.anchorNode)) {
    toolbar.hidden = true;
    return;
  }
  const rect = sel.getRangeAt(0).getBoundingClientRect();
  toolbar.style.top = `${rect.top + window.scrollY - 40}px`;
  toolbar.style.left = `${rect.left + window.scrollX}px`;
  toolbar.hidden = false;
};

document.addEventListener('selectionchange', () => {
  clearTimeout(timer);
  timer = setTimeout(positioniereToolbar, 100);
}, { signal: controller.signal });

// Aufräumen, z. B. beim Entfernen der Komponente:
// controller.abort();

Cursorposition in einer Textarea verfolgen

const textarea = document.querySelector('textarea');
const status = document.querySelector('#status');

// In neueren Browsern feuert das Ereignis direkt am Formularfeld
textarea.addEventListener('selectionchange', () => {
  const { selectionStart, selectionEnd } = textarea;
  status.textContent = selectionStart === selectionEnd
    ? `Cursor bei ${selectionStart}`
    : `Auswahl ${selectionStart}–${selectionEnd}`;
});
Cursor bei 12

// Wichtig · Fallstricke

  • Nur am Document: Für normale Auswahlen löst der Browser das Ereignis ausschließlich am Document aus, nicht an einzelnen Elementen. Ob die Auswahl in einem bestimmten Bereich liegt, prüfen Sie deshalb selbst, z. B. mit element.contains(selection.anchorNode).
  • Keine Details im Event-Objekt: Das Ereignis sagt nicht, was sich geändert hat. Lesen Sie die Auswahl immer über document.getSelection() aus.
  • Hohe Frequenz: Beim Ziehen mit der Maus oder bei gedrückten Pfeiltasten feuert das Ereignis sehr oft. Drosseln Sie Layout-Abfragen wie getBoundingClientRect() oder DOM-Änderungen (Debouncing oder requestAnimationFrame).
  • Endlosschleifen: Ändern Sie die Auswahl im Handler selbst, z. B. mit addRange(), löst das ein weiteres selectionchange aus. Schützen Sie sich davor mit einem Flag.
  • Nicht verwechseln mit selectstart: selectstart kommt nur zu Beginn einer Auswahl und lässt sich abbrechen. selectionchange kommt bei jeder Änderung und lässt sich nicht abbrechen. Das Ereignis select gibt es nur bei <input> und <textarea>.
  • Kompatibilität: Am Document wird das Ereignis von allen modernen Browsern unterstützt. Am Element (<input>/<textarea>) gibt es es erst in neueren Versionen (Firefox seit längerem, Chrome/Edge ab 127, Safari ab 17). Bei älteren Browsern hören Sie für Formularfelder zusätzlich auf select, keyup und mouseup.
  • Shadow DOM: Liegt die Auswahl in einem Shadow Root, ist document.getSelection() je nach Browser ungenau. Verwenden Sie dort, wo verfügbar, Selection.getComposedRanges().