Signatur
Beschreibung
setSelectionRange() markiert einen Textbereich in einem Eingabefeld oder setzt den Cursor an eine bestimmte Stelle. Die Positionen sind nullbasierte Zeichen-Indizes (UTF-16-Codeeinheiten). Sind Start und Ende gleich, wird keine Auswahl erzeugt, sondern nur der Cursor (Caret) an diese Stelle gesetzt.
Typische Einsatzfälle sind: den Cursor nach dem programmatischen Ändern von value an die richtige Stelle zurücksetzen (z. B. bei Eingabemasken für Telefonnummern oder IBANs), einen Teil des Inhalts vorauswählen (etwa den Dateinamen ohne Endung beim Umbenennen) oder Autovervollständigung, bei der der ergänzte Teil markiert bleibt und durch Weitertippen überschrieben wird.
Die Methode ist auch auf HTMLTextAreaElement verfügbar. Bei <input> funktioniert sie nur mit den Typen text, search, url, tel und password. Für andere Typen (z. B. email, number, date) wird eine InvalidStateError-DOMException geworfen.
Damit die Auswahl sichtbar wird, muss das Element in der Regel fokussiert sein — rufe also vorher focus() auf. Die aktuelle Auswahl kann über selectionStart, selectionEnd und selectionDirection ausgelesen werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $selectionStart Pflicht | number | null | Index des ersten ausgewählten Zeichens (nullbasiert). Werte größer als die Textlänge werden auf die Länge begrenzt. null wird wie 0 behandelt. |
|
| $selectionEnd Pflicht | number | null | Index hinter dem letzten ausgewählten Zeichen. Werte größer als die Textlänge werden auf die Länge begrenzt. Ist selectionEnd kleiner als selectionStart, werden beide auf selectionEnd gesetzt. |
|
| $selectionDirection | "forward" | "backward" | "none" | "none" | Richtung der Auswahl, also an welchem Ende der Cursor steht. Auf Systemen ohne Richtungskonzept (z. B. macOS teils) wird "none" wie "forward" behandelt. |
Rückgabewert
undefined). Löst ggf. ein select-Event bzw. selectionchange am Element aus.Beispiele
Dateinamen ohne Endung vorauswählen
// <input id="filename" type="text" value="urlaubsfoto.jpg">
const input = document.querySelector('#filename');
input.focus();
const dot = input.value.lastIndexOf('.');
const end = dot > 0 ? dot : input.value.length;
input.setSelectionRange(0, end);
console.log(input.value.slice(input.selectionStart, input.selectionEnd));
Cursor ans Ende setzen
// <textarea id="notiz">Erste Zeile\nZweite Zeile</textarea>
const area = document.querySelector('#notiz');
area.focus();
const len = area.value.length;
// Start = Ende → keine Auswahl, nur Cursorposition
area.setSelectionRange(len, len);
console.log(area.selectionStart, area.selectionEnd);
Eingabemaske: Cursorposition nach Formatierung erhalten
// <input id="iban" type="text">
const iban = document.querySelector('#iban');
iban.addEventListener('input', () => {
const pos = iban.selectionStart;
// Anzahl Nicht-Leerzeichen vor dem Cursor merken
const rawBefore = iban.value.slice(0, pos).replace(/\s/g, '').length;
const raw = iban.value.replace(/\s/g, '').toUpperCase();
iban.value = raw.replace(/(.{4})/g, '$1 ').trim();
// Neue Cursorposition berechnen (je 4 Zeichen ein Leerzeichen)
let newPos = rawBefore + Math.floor(rawBefore / 4);
if (rawBefore > 0 && rawBefore % 4 === 0) newPos -= 1;
iban.setSelectionRange(newPos, newPos);
});
Autovervollständigung mit markiertem Vorschlag
// <input id="stadt" type="search">
const staedte = ['Berlin', 'Bremen', 'Hamburg', 'München'];
const feld = document.querySelector('#stadt');
feld.addEventListener('input', (e) => {
if (e.inputType?.startsWith('delete')) return;
const getippt = feld.value;
const treffer = staedte.find((s) => s.toLowerCase().startsWith(getippt.toLowerCase()));
if (treffer && getippt) {
feld.value = getippt + treffer.slice(getippt.length);
// Ergänzten Teil markieren – Weitertippen überschreibt ihn
feld.setSelectionRange(getippt.length, treffer.length, 'backward');
}
});
// Wichtig · Fallstricke
- Nicht unterstützte Input-Typen: Bei
type="email",number,date,colorusw. wirft der Aufruf eineInvalidStateError-DOMException. Wer eine Auswahl in E-Mail-Feldern braucht, muss notfalls auftype="text"mitinputmode="email"ausweichen. Vor dem Aufruf lässt sich mittry…catchoder einer Prüfung vonselectionStart !== nullabsichern. - Fokus: Ohne Fokus wird die Auswahl zwar gespeichert, aber meist nicht angezeigt. Einige ältere Browser verschieben beim Aufruf den Fokus ungefragt. Auf iOS wirkt die Methode oft nur, wenn sie direkt in einer Nutzeraktion (z. B.
click,focus) aufgerufen wird. - Zeitpunkt beim Fokussieren: Im
focus-Handler setzt der Browser die Cursorposition bei Mausklick danach erneut. Den Aufruf daher ggf. mitrequestAnimationFrame()odersetTimeout(…, 0)verzögern. - Indizes sind UTF-16-Codeeinheiten: Emojis und andere Zeichen außerhalb der BMP zählen als 2. Wer mit
[...str].lengthrechnet, erhält abweichende Positionen. - Zeilenumbrüche in
<textarea>:valuenormalisiert Umbrüche auf\n; die Indizes beziehen sich auf diesen normalisierten Wert. - Zum Ersetzen des markierten Texts eignet sich
setRangeText()besser als manuelles String-Zusammenbauen, da dabei die Auswahl kontrolliert angepasst wird.