Signatur
Beschreibung
Das Ereignis textformatupdate der Schnittstelle EditContext wird ausgelöst, während ein Nutzer Text über einen Input Method Editor (IME) zusammensetzt, etwa bei chinesischer, japanischer oder koreanischer Eingabe. Das IME-Fenster teilt der Anwendung dabei mit, wie bestimmte Teile des Kompositionstextes dargestellt werden sollen, meist als durchgezogene, gepunktete oder wellenförmige Unterstreichung.
Mit einem EditContext übernimmt die Anwendung das Rendern des bearbeitbaren Textes selbst, zum Beispiel in einem <canvas> oder mit eigenem DOM-Aufbau. Deshalb zeichnet der Browser diese Formatierungen nicht automatisch. Die Anwendung muss auf textformatupdate reagieren und die Formatierungen selbst darstellen. Das Ereignisobjekt ist ein TextFormatUpdateEvent. Seine Methode getTextFormats() gibt ein Array von TextFormat-Objekten zurück, jeweils mit rangeStart, rangeEnd, underlineStyle ("none", "solid", "dotted", "dashed", "wavy") und underlineThickness ("none", "thin", "thick").
Den Handler registriert man entweder mit editContext.addEventListener("textformatupdate", handler) oder über die Eigenschaft editContext.ontextformatupdate = handler. Das Ereignis tritt meist zusammen mit textupdate, compositionstart und compositionend auf. Typischerweise entfernt man bei compositionend alle Formatierungen wieder.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "textformatupdate". |
|
| $handler Pflicht | (event: TextFormatUpdateEvent) => void | Callback, der ein TextFormatUpdateEvent erhält. Mit event.getTextFormats() liest man die Formatierungen aus. |
|
| $options | boolean | AddEventListenerOptions | false | Übliche Listener-Optionen wie once oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Die Daten stehen im Ereignisobjekt über getTextFormats() bereit, das ein TextFormat[] liefert.Beispiele
Formatierungen der IME-Komposition protokollieren
const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;
editContext.addEventListener('textformatupdate', (event) => {
for (const format of event.getTextFormats()) {
const { rangeStart, rangeEnd, underlineStyle, underlineThickness } = format;
console.log(`${rangeStart}-${rangeEnd}: ${underlineStyle}/${underlineThickness}`);
}
});
Unterstreichungen mit der CSS Custom Highlight API darstellen
// CSS: ::highlight(ime-solid) { text-decoration: underline solid; }
// ::highlight(ime-wavy) { text-decoration: underline wavy; }
const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;
const clearImeHighlights = () => {
for (const style of ['solid', 'dotted', 'dashed', 'wavy']) {
CSS.highlights.delete(`ime-${style}`);
}
};
editContext.addEventListener('textformatupdate', (event) => {
clearImeHighlights();
const textNode = editor.firstChild; // eigener Render-Text
if (!textNode) return;
for (const { rangeStart, rangeEnd, underlineStyle } of event.getTextFormats()) {
if (underlineStyle === 'none') continue;
const range = new Range();
range.setStart(textNode, rangeStart);
range.setEnd(textNode, rangeEnd);
const name = `ime-${underlineStyle}`;
const highlight = CSS.highlights.get(name) ?? new Highlight();
highlight.add(range);
CSS.highlights.set(name, highlight);
}
});
// Nach Abschluss der Komposition Formatierungen entfernen
editContext.addEventListener('compositionend', clearImeHighlights);
on-Property nutzen und Listener wieder entfernen
const editContext = new EditContext();
document.querySelector('#editor').editContext = editContext;
// Variante 1: on-Property
editContext.ontextformatupdate = (event) => {
console.log('Formate:', event.getTextFormats().length);
};
// Variante 2: benannter Listener, später abmelden
const onFormat = (event) => console.log(event.getTextFormats());
editContext.addEventListener('textformatupdate', onFormat);
// z. B. beim Zerstören des Editors
editContext.removeEventListener('textformatupdate', onFormat);
editContext.ontextformatupdate = null;
// Wichtig · Fallstricke
- Experimentelle API:
EditContextgibt es bisher nur in Chromium-Browsern (Chrome/Edge 121+). Prüfe die Unterstützung mit'EditContext' in windowund sieh einen Fallback wiecontenteditableoder<textarea>vor. - Das Ereignis wird am
EditContext-Objekt ausgelöst, nicht am zugehörigen DOM-Element. Ein Listener am Element empfängt es also nicht. rangeStartundrangeEndsind Positionen im Text desEditContext(editContext.text). Wenn die eigene Darstellung anders aufgebaut ist, zum Beispiel über mehrere Textknoten oder Zeilen verteilt, muss man die Positionen selbst umrechnen.- Die Werte für Stil und Stärke hängen vom Betriebssystem und vom IME ab. Unter Umständen wird das Ereignis nie ausgelöst, zum Beispiel bei lateinischer Tastatureingabe ohne Komposition.
- Entferne die Formatierungen bei
compositionend, sonst bleiben veraltete Unterstreichungen sichtbar.