Signatur
Beschreibung
TextUpdateEvent gehört zur EditContext API. Mit dieser API bauen Sie eigene Texteditoren, z. B. auf Basis von <canvas> oder mit eigenem DOM-Rendering. Das Betriebssystem und die Eingabemethode (IME, Bildschirmtastatur, Diktierfunktion) arbeiten dabei direkt mit einem EditContext-Objekt statt mit einem contenteditable-Element. Wenn der Benutzer tippt, einfügt, löscht oder eine Komposition abschließt, feuert der EditContext das Ereignis textupdate vom Typ TextUpdateEvent.
Das Ereignis beschreibt die Änderung genau:
updateRangeStart/updateRangeEnd: Zeichenbereich im alten Text, der ersetzt wird.text: der neu eingefügte Text (bei reinem Löschen ein leerer String).selectionStart/selectionEnd: Position der Auswahl bzw. des Cursors nach der Änderung.
Wenn das Ereignis eintrifft, hat der Browser editContext.text und die Auswahl bereits aktualisiert. Ihre Anwendung muss nur noch das eigene Datenmodell anpassen und die Darstellung neu zeichnen. Der Browser rendert bei der EditContext API nichts selbst, darum kümmern Sie sich komplett selbst.
Sie können das Ereignis auch mit new TextUpdateEvent(type, options) selbst erzeugen, zum Beispiel für Tests. Ein so erzeugtes und mit dispatchEvent() ausgelöstes Ereignis ändert den Zustand des EditContext aber nicht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, normalerweise "textupdate". |
|
| $options | object | {} | Optionales Objekt mit den Eigenschaften aus EventInit (bubbles, cancelable, composed) und zusätzlich den folgenden Feldern. |
| $options.updateRangeStart | number | 0 | Index des ersten ersetzten Zeichens (UTF-16-Codeeinheiten). |
| $options.updateRangeEnd | number | 0 | Index direkt hinter dem letzten ersetzten Zeichen. |
| $options.text | string | "" | Der eingefügte Ersatztext. |
| $options.selectionStart | number | 0 | Anfang der Auswahl nach der Änderung. |
| $options.selectionEnd | number | 0 | Ende der Auswahl nach der Änderung. Ist der Wert gleich selectionStart, gibt es nur einen Cursor und keine Auswahl. |
Rückgabewert
TextUpdateEvent-Objekt mit den schreibgeschützten Eigenschaften updateRangeStart, updateRangeEnd, text, selectionStart und selectionEnd.Beispiele
Ereignis selbst erzeugen und auslesen
// Simuliert: "Welt" (Index 6–10) wird durch "JS" ersetzt
const event = new TextUpdateEvent('textupdate', {
updateRangeStart: 6,
updateRangeEnd: 10,
text: 'JS',
selectionStart: 8,
selectionEnd: 8
});
console.log(event.type, event.text);
console.log(event.updateRangeStart, event.updateRangeEnd);
console.log(event.selectionStart, event.selectionEnd);
Einfacher eigener Editor mit EditContext
// HTML: <div id="editor" tabindex="0"></div>
const editorEl = document.querySelector('#editor');
if ('EditContext' in window) {
const editContext = new EditContext({ text: '' });
editorEl.editContext = editContext;
const render = () => {
const { text, selectionStart, selectionEnd } = editContext;
// Cursor als senkrechten Strich darstellen
editorEl.textContent =
text.slice(0, selectionStart) + '|' + text.slice(selectionEnd);
};
editContext.addEventListener('textupdate', (e) => {
console.log(
`Ersetze [${e.updateRangeStart}, ${e.updateRangeEnd}) durch "${e.text}"`
);
// editContext.text ist hier bereits aktualisiert
render();
});
render();
editorEl.focus();
} else {
editorEl.contentEditable = 'true'; // Fallback
}
Eigenes Datenmodell synchron halten
// Eigenes Modell, z. B. für Syntax-Highlighting
let model = 'Hallo Welt';
const applyUpdate = (e) => {
model =
model.slice(0, e.updateRangeStart) +
e.text +
model.slice(e.updateRangeEnd);
return model;
};
// Test mit einem selbst erzeugten Ereignis
const evt = new TextUpdateEvent('textupdate', {
updateRangeStart: 5,
updateRangeEnd: 10,
text: ', EditContext!',
selectionStart: 19,
selectionEnd: 19
});
console.log(applyUpdate(evt));
// Wichtig · Fallstricke
- Kompatibilität: Die EditContext API ist experimentell und bisher nur in Chromium-Browsern verfügbar (Chrome und Edge ab 121). Prüfen Sie die Unterstützung mit
'EditContext' in windowund bieten Sie einen Fallback an, z. B.contenteditableoder<textarea>. - Nicht abbrechbar:
preventDefault()hat keine Wirkung. Der Text imEditContextist beim Eintreffen des Ereignisses schon geändert. Wenn Sie eine Eingabe ablehnen wollen, setzen Sie sie miteditContext.updateText()undupdateSelection()zurück. - Indizes in UTF-16: Alle Positionen zählen UTF-16-Codeeinheiten. Emojis und andere Zeichen außerhalb der BMP belegen deshalb zwei Positionen.
- Kein automatisches Rendern: Der Browser zeichnet weder Text noch Cursor. Außerdem sollten Sie
updateControlBounds(),updateSelectionBounds()und beicharacterboundsupdateauchupdateCharacterBounds()aufrufen, damit das IME-Fenster an der richtigen Stelle erscheint. - Bei IME-Kompositionen (z. B. Japanisch oder Chinesisch) feuert
textupdatemehrmals. Formatierungen für den Kompositionstext kommen über das Ereignistextformatupdate. - Nicht jede Eingabe löst
textupdateaus: Enter, Rück- und Entfernen-Taste mit Strg sowie Tastenkombinationen kommen teilweise alskeydown/beforeinputam Element an und müssen dort behandelt werden.