Signatur
Beschreibung
window.getSelection() liefert das Selection-Objekt, das zum document des Fensters gehört. Es beschreibt, welchen Textbereich der Benutzer gerade markiert hat, oder bei einer leeren Auswahl nur die Position des Carets (Einfügemarke), etwa in einem contenteditable-Element.
Typische Einsatzgebiete sind Rich-Text-Editoren, Funktionen zum Teilen oder Zitieren markierter Stellen, Tooltips und Kontextmenüs, die über einer Auswahl erscheinen, sowie das Auswählen oder Aufheben einer Markierung per Code. Über selection.toString() bekommst du den reinen Text, mit getRangeAt(0) ein Range-Objekt samt Position und DOM-Knoten.
Das zurückgegebene Objekt ist live: Der Browser gibt bei jedem Aufruf dasselbe Objekt zurück und aktualisiert es, wenn sich die Auswahl ändert. Wenn du einen bestimmten Zustand festhalten willst, kopiere die Werte (z. B. mit toString() oder getRangeAt(0).cloneRange()). document.getSelection() funktioniert gleich und liefert dasselbe Objekt.
Rückgabewert
Selection-Objekt des Dokuments. In Firefox kann der Rückgabewert null sein, wenn er in einem nicht dargestellten <iframe> (display: none) aufgerufen wird.Beispiele
Markierten Text auslesen
document.addEventListener('mouseup', () => {
const selection = window.getSelection();
const text = selection?.toString().trim() ?? '';
if (text) {
console.log(`Markiert: "${text}" (${selection.rangeCount} Bereich)`);
}
});
Position der Auswahl für einen Tooltip ermitteln
const tooltip = document.querySelector('#share-tooltip');
document.addEventListener('selectionchange', () => {
const sel = window.getSelection();
if (!sel || sel.isCollapsed || sel.rangeCount === 0) {
tooltip.hidden = true;
return;
}
const rect = sel.getRangeAt(0).getBoundingClientRect();
tooltip.style.top = `${rect.top + window.scrollY - 40}px`;
tooltip.style.left = `${rect.left + window.scrollX + rect.width / 2}px`;
tooltip.hidden = false;
});
Inhalt eines Elements per Code markieren und kopieren
const selectAndCopy = async (element) => {
const range = document.createRange();
range.selectNodeContents(element);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
await navigator.clipboard.writeText(sel.toString());
console.log('Kopiert:', sel.toString());
};
document.querySelector('#copy-btn')
.addEventListener('click', () => selectAndCopy(document.querySelector('pre code')));
Caret-Position in einem contenteditable-Element
const editor = document.querySelector('[contenteditable]');
editor.addEventListener('keyup', () => {
const sel = window.getSelection();
if (sel.rangeCount === 0) return;
const { startContainer, startOffset } = sel.getRangeAt(0);
console.log('Caret in Knoten:', startContainer.nodeName, 'Offset:', startOffset);
});
// Wichtig · Fallstricke
- Formularfelder: Bei Text in
<input>und<textarea>gibtgetSelection().toString()in Firefox (und je nach Browser auch anderswo) eine leere Zeichenkette zurück. Nutze stattdessenel.value.substring(el.selectionStart, el.selectionEnd). - Immer
rangeCountprüfen:getRangeAt(0)wirft einenIndexSizeError, wenn nichts ausgewählt ist (rangeCount === 0). - Live-Objekt: Es wird bei jedem Aufruf dasselbe Objekt zurückgegeben. Wenn du einen Zustand speichern willst, nimm
cloneRange()oder den Text. - Mehrere Bereiche: Nur Firefox unterstützt mehrere Bereiche (Strg-Auswahl). Andere Browser haben höchstens einen Bereich.
- Shadow DOM: Über Shadow-Grenzen hinweg sind die Knoten der Auswahl unzuverlässig. Neuere Browser bieten dafür
Selection.getComposedRanges()an. - Sicherheit: Markierten Text nie ungeprüft mit
innerHTMLeinfügen, sonst droht XSS. VerwendetextContent. - Das Ereignis
selectionchangewird sehr oft ausgelöst. Rechenintensive Handler sollten gedrosselt werden (Debounce/Throttle).