Signatur
Beschreibung
getRangeAt() liefert einen der Bereiche (Range), aus denen eine Auswahl (Selection) besteht. Die Auswahl bekommt man über window.getSelection() oder document.getSelection(). Das zurückgegebene Range-Objekt gibt Start- und Endpunkt der Auswahl im DOM genau an. Damit lässt sich markierter Text auslesen, umschließen, löschen oder ausmessen.
In der Praxis ruft man fast immer getRangeAt(0) auf. Nur Firefox unterstützt mehrere gleichzeitige Bereiche, etwa durch Strg-Klick oder die Auswahl von Tabellenzellen. Chromium und WebKit kennen höchstens einen Bereich. Ob überhaupt ein Bereich vorhanden ist, zeigt selection.rangeCount. Das sollte man vor dem Aufruf prüfen.
Typische Einsatzfälle:
- Rich-Text-Editoren mit
contenteditable, zum Beispiel um markierten Text fett zu setzen oder hervorzuheben - Kontextmenüs oder Tooltips an der Position der Auswahl anzeigen (
range.getBoundingClientRect()) - Die Cursorposition merken und später wiederherstellen
Das zurückgegebene Objekt ist eine Referenz auf den aktiven Bereich. Wer es verändert (setStart(), collapse() usw.), ändert je nach Browser direkt die sichtbare Auswahl. Wer den Zustand dauerhaft speichern will, nimmt eine Kopie mit range.cloneRange().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $index Pflicht | number | Nullbasierter Index des gewünschten Bereichs. Er muss zwischen 0 und selection.rangeCount - 1 liegen, sonst wird ein IndexSizeError geworfen. |
Rückgabewert
Range-Objekt am angegebenen Index. Es verweist auf den aktiven Auswahlbereich und ist keine Kopie.Beispiele
Markierten Text und Container auslesen
document.addEventListener('mouseup', () => {
const selection = window.getSelection();
// Ohne Bereich würde getRangeAt(0) einen Fehler werfen
if (selection.rangeCount === 0 || selection.isCollapsed) return;
const range = selection.getRangeAt(0);
console.log('Text:', range.toString());
console.log('Start-Offset:', range.startOffset);
console.log('Gemeinsamer Container:', range.commonAncestorContainer.nodeName);
});
Auswahl mit <mark> hervorheben
const highlightSelection = () => {
const selection = window.getSelection();
if (!selection.rangeCount) return;
const range = selection.getRangeAt(0);
const mark = document.createElement('mark');
try {
// Klappt nur, wenn die Auswahl keine Elementgrenzen halb schneidet
range.surroundContents(mark);
} catch {
// Rückfall: Inhalt herauslösen und eingepackt wieder einfügen
mark.appendChild(range.extractContents());
range.insertNode(mark);
}
selection.removeAllRanges();
};
document.querySelector('#highlight-btn').addEventListener('click', highlightSelection);
Tooltip an der Auswahl positionieren
const tooltip = document.querySelector('#tooltip');
document.addEventListener('selectionchange', () => {
const sel = document.getSelection();
if (!sel.rangeCount || sel.isCollapsed) {
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;
});
Cursorposition in contenteditable sichern und wiederherstellen
const editor = document.querySelector('[contenteditable]');
let savedRange = null;
editor.addEventListener('blur', () => {
const sel = window.getSelection();
if (sel.rangeCount) {
// Kopie anlegen, weil die Referenz sonst mitverändert wird
savedRange = sel.getRangeAt(0).cloneRange();
}
});
const restoreCursor = () => {
if (!savedRange) return;
editor.focus();
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(savedRange);
};
// Wichtig · Fallstricke
- IndexSizeError: Ist
rangeCountgleich0, etwa wenn noch nie geklickt wurde oder nachremoveAllRanges(), wirftgetRangeAt(0)eineDOMException. Prüfe deshalb immer vorherselection.rangeCount > 0. - Mehrere Bereiche: Nur Firefox unterstützt mehrere Bereiche. In Chrome, Edge und Safari ist
rangeCounthöchstens1. Code, der auf mehrere Bereiche angewiesen ist, funktioniert dort also nicht. - Referenz statt Kopie: Änderungen am zurückgegebenen
Rangekönnen die sichtbare Auswahl direkt verändern. Zum Speichern istcloneRange()nötig. - Formularfelder: Bei Auswahlen in
<input>und<textarea>liefert der Bereich nicht den ausgewählten Text innerhalb des Feldes. Dafür gibt esselectionStartundselectionEnddes Elements. - Shadow DOM: Auswahlen in Shadow Roots sind je nach Browser nicht vollständig sichtbar. Neuere Browser bieten dafür
Selection.getComposedRanges(). - Einfügen von HTML: Wer aus Nutzereingaben HTML baut und per
range.insertNode()einfügt, sollte die Eingaben bereinigen, sonst droht XSS.