Signatur
Beschreibung
Das Interface CharacterBoundsUpdateEvent gehört zur EditContext API. Ein Ereignis dieses Typs heißt characterboundsupdate und wird an einer EditContext-Instanz ausgelöst, wenn das Betriebssystem wissen muss, wo bestimmte Zeichen auf dem Bildschirm stehen. Das braucht es zum Beispiel, um das Kandidatenfenster eines Eingabemethoden-Editors (IME) bei der Eingabe von Japanisch oder Chinesisch direkt neben dem gerade getippten Text anzuzeigen.
Wichtig ist das vor allem für selbst gezeichnete Editoren, etwa Code- oder Texteditoren, die ihren Inhalt in ein <canvas> zeichnen oder eine eigene DOM-Struktur verwenden. Der Browser kennt die Position der Zeichen in solchen Fällen nicht, also muss die Anwendung sie liefern. Das Ereignis enthält dazu mit rangeStart und rangeEnd den Zeichenbereich, für den Positionen gebraucht werden.
Als Antwort ruft die Anwendung EditContext.prototype.updateCharacterBounds(rangeStart, bounds) auf. Dabei übergibt sie für jedes Zeichen im Bereich ein DOMRect in Viewport-Koordinaten. Das Interface erbt von Event. Den Handler registrierst du entweder mit editContext.addEventListener("characterboundsupdate", handler) oder über die Eigenschaft editContext.oncharacterboundsupdate.
rangeStart(nur lesbar,number): Position (Offset) des ersten Zeichens, dessen Begrenzungsrahmen angefordert wird.rangeEnd(nur lesbar,number): Position (Offset) direkt hinter dem letzten angeforderten Zeichen, also exklusiv.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, normalerweise "characterboundsupdate" (Parameter des Konstruktors). |
|
| $options | { rangeStart?: number, rangeEnd?: number } & EventInit | {} | Optionales Objekt für den Konstruktor. Legt rangeStart und rangeEnd fest (Standard jeweils 0) und nimmt zusätzlich die üblichen EventInit-Felder wie bubbles oder cancelable an. |
Rückgabewert
new CharacterBoundsUpdateEvent(type, options) liefert ein neues Ereignisobjekt. Die Eigenschaften rangeStart und rangeEnd sind jeweils vom Typ number.Beispiele
Auf Unterstützung prüfen und Ereignis selbst erzeugen
if ('EditContext' in window && 'CharacterBoundsUpdateEvent' in window) {
const evt = new CharacterBoundsUpdateEvent('characterboundsupdate', {
rangeStart: 3,
rangeEnd: 7
});
console.log(evt.type, evt.rangeStart, evt.rangeEnd);
} else {
console.log('EditContext API wird nicht unterstützt');
}
Zeichenpositionen für einen Canvas-Editor liefern
const canvas = document.querySelector('#editor');
const ctx2d = canvas.getContext('2d');
ctx2d.font = '16px monospace';
const editContext = new EditContext({ text: 'Hallo Welt' });
canvas.editContext = editContext;
const LINE_HEIGHT = 20;
const PADDING = 10;
editContext.addEventListener('characterboundsupdate', (e) => {
const canvasRect = canvas.getBoundingClientRect();
const bounds = [];
for (let i = e.rangeStart; i < e.rangeEnd; i++) {
const x = ctx2d.measureText(editContext.text.slice(0, i)).width;
const w = ctx2d.measureText(editContext.text[i] ?? ' ').width;
// Koordinaten relativ zum Viewport angeben
bounds.push(new DOMRect(canvasRect.left + PADDING + x, canvasRect.top + PADDING, w, LINE_HEIGHT));
}
editContext.updateCharacterBounds(e.rangeStart, bounds);
console.log(`Positionen für ${bounds.length} Zeichen gemeldet`);
});
Handler über die on-Property setzen und Listener wieder entfernen
const editContext = new EditContext();
document.querySelector('#editor').editContext = editContext;
const logRange = (e) => console.log('Angefragt:', e.rangeStart, '–', e.rangeEnd);
// Variante 1: Eigenschaft (ersetzt einen vorher gesetzten Handler)
editContext.oncharacterboundsupdate = logRange;
// Variante 2: Listener hinzufügen und später wieder entfernen
editContext.addEventListener('characterboundsupdate', logRange);
editContext.removeEventListener('characterboundsupdate', logRange);
// Handler über die Eigenschaft deaktivieren
editContext.oncharacterboundsupdate = null;
// Wichtig · Fallstricke
- Experimentell: Bisher nur in Chromium-Browsern verfügbar (Chrome und Edge ab 121). Firefox und Safari unterstützen die API nicht. Prüfe sie daher vorab mit
'EditContext' in windowund sieh eine Ersatzlösung vor, z. B.contenteditableoder ein verstecktes<textarea>. rangeEndist exklusiv. Das Array fürupdateCharacterBounds()braucht also genaurangeEnd - rangeStartEinträge.- Die
DOMRect-Werte müssen in Viewport-Koordinaten angegeben werden, nicht relativ zum Canvas. Rechne deshalb den Wert vongetBoundingClientRect()und den aktuellen Scroll-Versatz ein, sonst erscheint das IME-Fenster an der falschen Stelle. - Beantworte das Ereignis zügig. Wenn du nicht antwortest, positioniert das Betriebssystem das Kandidatenfenster nur ungefähr. Hilfreich ist es außerdem, bei Layout-Änderungen (Scrollen, Größenänderung)
updateControlBounds()undupdateSelectionBounds()aufzurufen. - Das Ereignis wird an der
EditContext-Instanz ausgelöst, nicht am DOM-Element.