Signatur
Beschreibung
TextFormatUpdateEvent gehört zur EditContext API. Das Ereignis wird als textformatupdate auf einer EditContext-Instanz ausgelöst, während ein Input Method Editor (IME) aktiv ist. Das kommt z. B. bei der Eingabe von Japanisch, Chinesisch oder Koreanisch vor, und auch bei manchen virtuellen Tastaturen. Der IME legt dabei fest, wie der noch nicht bestätigte Kompositionstext aussehen soll: meist unterstrichen, wobei das gerade umgewandelte Segment oft dicker unterstrichen wird.
Ist ein Element über element.editContext mit einem EditContext verbunden, übernimmt der Browser das Zeichnen des Textes nicht mehr selbst. Die Anwendung ist dann auch für die Darstellung dieser IME-Formate zuständig. Die Methode getTextFormats() gibt ein Array von TextFormat-Objekten zurück. Jedes davon hat diese Eigenschaften:
rangeStart/rangeEnd: Zeichenpositionen (UTF-16-Offsets) im Text desEditContext,underlineStyle:"none","solid","dotted","dashed"oder"wavy",underlineThickness:"none","thin"oder"thick".
Sinnvoll ist das Ereignis vor allem für eigene Editoren, etwa Code-Editoren, Canvas-basierte Editoren oder Rich-Text-Komponenten, die sich bei der IME-Eingabe wie native Eingabefelder anfühlen sollen. Zum Darstellen eignet sich besonders die CSS Custom Highlight API. Bei Canvas-Editoren zeichnet man die Unterstreichungen direkt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter von new TextFormatUpdateEvent(type, options): der Ereignisname, in der Praxis "textformatupdate". |
|
| $options | { textFormats?: TextFormat[] } & EventInit | {} | Optionales Objekt. textFormats ist ein Array von TextFormat-Objekten, das später getTextFormats() zurückgibt. Außerdem sind die üblichen EventInit-Felder wie bubbles und cancelable erlaubt. |
Rückgabewert
getTextFormats() gibt ein TextFormat[] zurück.Beispiele
IME-Formate eines EditContext auslesen
const editorEl = document.getElementById("editor");
if ("EditContext" in window) {
const editContext = new EditContext();
editorEl.editContext = editContext;
editContext.addEventListener("textformatupdate", (event) => {
for (const format of event.getTextFormats()) {
console.log(
`Zeichen ${format.rangeStart}–${format.rangeEnd}: ` +
`${format.underlineStyle} / ${format.underlineThickness}`
);
}
});
} else {
console.warn("EditContext API wird nicht unterstützt.");
}
Unterstreichungen mit der CSS Custom Highlight API zeichnen
// CSS (Stylesheet):
// ::highlight(ime-thin) { text-decoration: underline 1px; }
// ::highlight(ime-thick) { text-decoration: underline 3px; }
const editorEl = document.getElementById("editor");
const editContext = new EditContext({ text: "" });
editorEl.editContext = editContext;
const render = () => {
editorEl.textContent = editContext.text; // ergibt einen einzigen Textknoten
};
editContext.addEventListener("textupdate", render);
editContext.addEventListener("textformatupdate", (event) => {
const thin = new Highlight();
const thick = new Highlight();
const textNode = editorEl.firstChild;
if (!textNode) return;
for (const f of event.getTextFormats()) {
if (f.underlineStyle === "none") continue;
const range = document.createRange();
range.setStart(textNode, f.rangeStart);
range.setEnd(textNode, f.rangeEnd);
(f.underlineThickness === "thick" ? thick : thin).add(range);
}
CSS.highlights.set("ime-thin", thin);
CSS.highlights.set("ime-thick", thick);
});
// Nach Ende der Komposition die Markierungen entfernen
editContext.addEventListener("compositionend", () => {
CSS.highlights.delete("ime-thin");
CSS.highlights.delete("ime-thick");
});
Synthetisches Ereignis für Tests erzeugen
const editContext = new EditContext({ text: "かんじ" });
editContext.addEventListener("textformatupdate", (e) => {
console.log(e.getTextFormats().length, e.getTextFormats()[0].underlineStyle);
});
const event = new TextFormatUpdateEvent("textformatupdate", {
textFormats: [
new TextFormat({
rangeStart: 0,
rangeEnd: 3,
underlineStyle: "wavy",
underlineThickness: "thin"
})
]
});
editContext.dispatchEvent(event);
// Wichtig · Fallstricke
- Experimentell: Nur Chromium-Browser (Chrome/Edge ab 121) unterstützen die API. Prüfe vorher mit
"EditContext" in window, ob sie verfügbar ist, und sieh einen Fallback vor, z. B.contenteditableoder<textarea>. - Das Ereignis wird nur auf dem
EditContextausgelöst, nicht auf dem verbundenen DOM-Element. Ein Listener am Element empfängt es nicht. - Jedes Ereignis enthält den vollständigen aktuellen Satz an Formaten. Verwirf deshalb vorher gezeichnete Unterstreichungen, statt neue hinzuzufügen.
rangeStart/rangeEndsind UTF-16-Offsets im Text desEditContext, nicht im DOM. Verteilt dein Editor den Text auf mehrere Knoten, musst du die Offsets selbst auf Knoten und Positionen umrechnen.- Ob und welche Formate geliefert werden, hängen vom Betriebssystem und vom IME ab. Unter manchen Plattformen kommt nur
"solid"/"thin"oder gar kein Ereignis. Verlasse dich daher nicht auf bestimmte Stile.