Start · Sprachen · JavaScript · Referenz · EditContext: compositionstart

EditContext: compositionstart

Ereignis

Wird an einem <code>EditContext</code> ausgelöst, sobald eine IME-Komposition beginnt, etwa beim Tippen japanischer, chinesischer oder koreanischer Zeichen.

seit JavaScript Experimentell: Chromium 121+ (Chrome, Edge); nicht Kategorie: webapi

Signatur

editContext.addEventListener("compositionstart", handler)

Beschreibung

Das Ereignis compositionstart des EditContext-Interfaces zeigt an, dass der Nutzer über einen Input Method Editor (IME) mit einer Komposition beginnt. Das passiert zum Beispiel, wenn ein Kandidatenfenster für japanische Kana/Kanji erscheint, wenn Pinyin eingegeben wird oder wenn auf Mobilgeräten eine Autokorrektur- bzw. Vorschlagsleiste aktiv wird. Beim Aufruf ist noch kein Text eingefügt: Der vorläufige Text der Komposition kommt erst danach über textupdate-Ereignisse an.

Mit der EditContext-API baut man eigene Editoren, etwa auf Basis von <canvas> oder mit komplett eigenem Rendering. Solche Editoren müssen selbst entscheiden, wie sie noch nicht bestätigten Text darstellen. compositionstart eignet sich, um einen internen Zustand wie „Komposition läuft“ zu setzen, Tastenkürzel und Undo-Gruppierung vorübergehend auszusetzen oder die Darstellung vorzubereiten, zum Beispiel für eine Unterstreichung, die dann bei textformatupdate gezeichnet wird.

Das Ereignis ist ein einfaches Event (kein CompositionEvent wie beim DOM-Ereignis auf Elementen). Es lässt sich nicht abbrechen und steigt nicht auf (kein Bubbling). Den Handler registriert man entweder mit addEventListener("compositionstart", …) oder über die Eigenschaft editContext.oncompositionstart. Das Gegenstück ist compositionend.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, hier immer "compositionstart".
$handler Pflicht (event: Event) => void Callback, der beim Start der Komposition aufgerufen wird. Er bekommt ein einfaches Event; event.target ist die EditContext-Instanz.
$options boolean | AddEventListenerOptions false Die üblichen Optionen von addEventListener, z. B. { once: true } oder { signal } zum Entfernen per AbortController.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Auch der Rückgabewert des Handlers wird ignoriert.

Beispiele

Kompositionszustand per addEventListener verfolgen

const editorEl = document.querySelector('#editor');
const editContext = new EditContext();
editorEl.editContext = editContext;

let composing = false;

editContext.addEventListener('compositionstart', () => {
  composing = true;
  editorEl.classList.add('is-composing');
  console.log('IME-Komposition gestartet');
});

editContext.addEventListener('compositionend', () => {
  composing = false;
  editorEl.classList.remove('is-composing');
  console.log('IME-Komposition beendet');
});

editContext.addEventListener('textupdate', (e) => {
  console.log(composing ? 'vorläufig:' : 'bestätigt:', e.text);
});
IME-Komposition gestartet vorläufig: k vorläufig: か IME-Komposition beendet

Handler über die on-Property setzen und wieder entfernen

const canvas = document.querySelector('canvas');
const editContext = new EditContext();
canvas.editContext = editContext;

editContext.oncompositionstart = (event) => {
  console.log('Start an:', event.target === editContext);
};

// Später, z. B. beim Zerstören des Editors:
const destroyEditor = () => {
  editContext.oncompositionstart = null;
  canvas.editContext = null;
};
Start an: true

Tastenkürzel während der Komposition sperren, Aufräumen per AbortController

const el = document.querySelector('#code-editor');
const editContext = new EditContext({ text: '' });
el.editContext = editContext;

const controller = new AbortController();
const { signal } = controller;
let imeActive = false;

editContext.addEventListener('compositionstart', () => {
  imeActive = true;
}, { signal });

editContext.addEventListener('compositionend', () => {
  imeActive = false;
}, { signal });

el.addEventListener('keydown', (e) => {
  // Enter bestätigt während der Komposition den IME-Kandidaten und darf nicht als Zeilenumbruch zählen
  if (imeActive) return;
  if (e.key === 'Enter') console.log('Neue Zeile einfügen');
}, { signal });

// Alle Listener auf einmal entfernen
const teardown = () => controller.abort();

// Wichtig · Fallstricke

  • Experimentell und nur in Chromium: Die EditContext-API gibt es in Chrome und Edge ab Version 121. Firefox und Safari unterstützen sie nicht. Prüfen Sie die Unterstützung mit 'EditContext' in window und sehen Sie ein contenteditable- oder <textarea>-Fallback vor.
  • Kein CompositionEvent: Anders als bei compositionstart auf DOM-Elementen gibt es hier keine Eigenschaft data. Den Text liefern erst die folgenden textupdate-Ereignisse (updateRangeStart, updateRangeEnd, text).
  • Ist einem Element ein EditContext zugeordnet, werden die Ereignisse vor allem am EditContext ausgelöst. Verlassen Sie sich für den Kompositionszustand nicht auf compositionstart-Listener am Element selbst.
  • Das Ereignis kommt nur, wenn das Element mit dem EditContext den Fokus hat und tatsächlich ein IME oder eine Vorschlagsleiste aktiv ist. Mit einer normalen westlichen Tastatur tritt es oft nie auf. Testen Sie deshalb mit echten IMEs (Japanisch, Chinesisch, Koreanisch) und auf Android-Tastaturen.
  • Das Ereignis lässt sich nicht abbrechen: preventDefault() hat keine Wirkung. Die Komposition kann nur mit compositionend abgeschlossen werden. Ein Fokuswechsel beendet sie ebenfalls.
  • keydown während einer Komposition: Prüfen Sie zusätzlich event.isComposing, damit z. B. Enter oder Escape nicht doppelt verarbeitet werden.