Signatur
Beschreibung
Die Methode getTextFormats() gehört zur EditContext API. Sie wird im Handler des Ereignisses textformatupdate aufgerufen, das ein EditContext auslöst. Das passiert, während ein Eingabemethoden-Editor (IME) Text zusammensetzt (Komposition), etwa bei der Eingabe von Japanisch, Chinesisch oder Koreanisch. Der IME teilt damit mit, welche Textbereiche wie hervorgehoben werden sollen, meist durch verschiedene Unterstreichungen für den bereits umgewandelten und den noch aktiven Teil.
Jedes zurückgegebene TextFormat-Objekt hat diese Eigenschaften:
rangeStart/rangeEnd: Zeichen-Offsets im Text desEditContextunderlineStyle:"none","solid","dotted","dashed"oder"wavy"underlineThickness:"none","thin"oder"thick"
Mit einem EditContext übernimmt Ihre Anwendung das Darstellen des Textes selbst, z. B. in einem eigenen Editor oder auf einem <canvas>. Deshalb müssen Sie diese Formate auch selbst anzeigen. Das geht gut mit der CSS Custom Highlight API (Highlight, CSS.highlights) oder durch direktes Zeichnen auf dem Canvas.
Rückgabewert
TextFormat-Objekten, eines pro formatiertem Bereich des Kompositionstextes. Das Array kann leer sein.Beispiele
IME-Formate protokollieren
const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;
editContext.addEventListener('textformatupdate', (event) => {
const formats = event.getTextFormats();
for (const f of formats) {
console.log(
`Bereich ${f.rangeStart}–${f.rangeEnd}: ` +
`${f.underlineStyle}, ${f.underlineThickness}`
);
}
});
Formate mit der CSS Custom Highlight API darstellen
// CSS dazu, z. B.:
// ::highlight(ime-solid-thin) { text-decoration: underline solid 1px; }
// ::highlight(ime-solid-thick) { text-decoration: underline solid 3px; }
// ::highlight(ime-dashed-thin) { text-decoration: underline dashed 1px; }
const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;
// Wichtig: Der Text muss selbst ins DOM gerendert werden (textupdate-Handler)
editContext.addEventListener('textupdate', () => {
editor.textContent = editContext.text;
});
editContext.addEventListener('textformatupdate', (event) => {
// Alte IME-Hervorhebungen entfernen
for (const name of [...CSS.highlights.keys()]) {
if (name.startsWith('ime-')) CSS.highlights.delete(name);
}
const textNode = editor.firstChild;
if (!textNode) return;
for (const { rangeStart, rangeEnd, underlineStyle, underlineThickness } of event.getTextFormats()) {
if (underlineStyle === 'none') continue;
const range = new Range();
range.setStart(textNode, rangeStart);
range.setEnd(textNode, rangeEnd);
const name = `ime-${underlineStyle}-${underlineThickness}`;
const highlight = CSS.highlights.get(name) ?? new Highlight();
highlight.add(range);
CSS.highlights.set(name, highlight);
}
});
Unterstreichungen auf einem Canvas zeichnen
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const editContext = new EditContext();
canvas.editContext = editContext;
let formats = [];
const render = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = '20px sans-serif';
ctx.fillText(editContext.text, 10, 30);
for (const f of formats) {
if (f.underlineStyle === 'none') continue;
const x1 = 10 + ctx.measureText(editContext.text.slice(0, f.rangeStart)).width;
const x2 = 10 + ctx.measureText(editContext.text.slice(0, f.rangeEnd)).width;
ctx.lineWidth = f.underlineThickness === 'thick' ? 3 : 1;
ctx.setLineDash(f.underlineStyle === 'dashed' ? [4, 2] : f.underlineStyle === 'dotted' ? [1, 2] : []);
ctx.beginPath();
ctx.moveTo(x1, 36);
ctx.lineTo(x2, 36);
ctx.stroke();
}
};
editContext.addEventListener('textupdate', render);
editContext.addEventListener('textformatupdate', (e) => {
formats = e.getTextFormats();
render();
});
editContext.addEventListener('compositionend', () => {
formats = [];
render();
});
// Wichtig · Fallstricke
Kompatibilität: Die EditContext API ist experimentell und bisher nur in Chromium-Browsern verfügbar (Chrome/Edge ab 121). Firefox und Safari unterstützen sie nicht. Prüfen Sie vorher die Unterstützung, z. B. mit if ('EditContext' in window), und sehen Sie für andere Browser einen Rückfall auf contenteditable oder <textarea> vor.
- Die Offsets beziehen sich auf
editContext.textund nicht auf DOM-Knoten. Wenn Ihr Editor den Text auf mehrere Knoten verteilt, müssen Sie die Offsets selbst auf die richtigen Knoten umrechnen. - Das Ereignis wird oft ausgelöst, bei manchen IMEs bei jedem Tastendruck. Entfernen Sie deshalb alte Hervorhebungen, bevor Sie neue setzen. Sonst sammeln sie sich an.
- Nach
compositionendsollten Sie die IME-Formatierung wieder entfernen. - Ob und wie Formate gesendet werden, hängt stark von IME und Betriebssystem ab. Verlassen Sie sich nicht auf bestimmte Stile oder eine bestimmte Anzahl von Bereichen.