Start · Sprachen · JavaScript · Referenz · Element: compositionend

Element: compositionend

Ereignis

Wird ausgelöst, wenn ein Textkompositionssystem wie ein Eingabemethoden-Editor (IME) die aktuelle Kompositionssitzung abschließt oder abbricht.

seit JavaScript Baseline: alle Browser (seit 2015 breit unterstütz Kategorie: webapi

Signatur

element.addEventListener("compositionend", handler)

Beschreibung

Das Ereignis compositionend gehört zu den Kompositionsereignissen (compositionstart, compositionupdate, compositionend). Es wird ausgelöst, sobald eine Eingabemethode (IME) die Zusammensetzung von Text beendet. Das passiert z. B. bei der Eingabe von Chinesisch, Japanisch oder Koreanisch, bei Akzentzeichen über Tottasten, bei der Sprachdiktierfunktion oder bei Autokorrektur auf Mobilgeräten. Beendet wird die Sitzung, wenn der Nutzer einen Kandidaten bestätigt, die Komposition abbricht (etwa mit Esc) oder der Fokus wechselt.

Der Handler erhält ein CompositionEvent. Die Eigenschaft data enthält den endgültig übernommenen Text. Bei einem Abbruch ist sie meist ein leerer String. Das Ereignis bubbelt, lässt sich aber nicht abbrechen: preventDefault() hat keine Wirkung.

Der wichtigste Anwendungsfall: Logik, die an input- oder keydown-Ereignissen hängt (Live-Suche, Validierung, Tastenkürzel, Zeichenzähler), soll während der Komposition pausieren und erst nach compositionend mit dem fertigen Text laufen. Sonst verarbeitet die Anwendung unfertige Zwischenstände wie „k“, „ka“, „かん“ statt des gewünschten „漢字“.

Registrieren lässt sich das Ereignis mit addEventListener("compositionend", …) oder über die Eigenschaft oncompositionend. Die Eigenschaft ist allerdings nicht in allen Browsern als IDL-Attribut vorhanden, deshalb ist addEventListener die sicherere Wahl.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "compositionend".
$handler Pflicht (event: CompositionEvent) => void Callback, der ein CompositionEvent erhält. Wichtige Eigenschaften: event.data (übernommener Text, bei Abbruch meist ""), event.locale (veraltet, meist leer), event.target.
$options boolean | AddEventListenerOptions false Optionen wie { once: true }, { capture: true } oder { signal } zum späteren Entfernen über einen AbortController.

Beispiele

Übernommenen IME-Text protokollieren

const input = document.querySelector('#name');

input.addEventListener('compositionstart', () => {
  console.log('Komposition gestartet');
});

input.addEventListener('compositionend', (event) => {
  // event.data enthält den bestätigten Text
  console.log(`Übernommen: "${event.data}"`);
});
Komposition gestartet Übernommen: "漢字"

Live-Suche erst nach abgeschlossener Komposition auslösen

const search = document.querySelector('#search');
let composing = false;

const runSearch = async (term) => {
  if (!term) return;
  const res = await fetch(`/api/search?q=${encodeURIComponent(term)}`);
  const hits = await res.json();
  console.log(`${hits.length} Treffer für "${term}"`);
};

search.addEventListener('compositionstart', () => { composing = true; });

search.addEventListener('compositionend', (event) => {
  composing = false;
  // In manchen Browsern kommt kein weiteres input-Event, daher hier explizit suchen
  runSearch(event.target.value);
});

search.addEventListener('input', (event) => {
  // Zwischenstände der IME ignorieren
  if (composing || event.isComposing) return;
  runSearch(event.target.value);
});
3 Treffer für "東京"

Enter-Taste nicht während der Komposition abschicken

const chat = document.querySelector('#chat-input');

chat.addEventListener('keydown', (event) => {
  // Enter bestätigt bei IMEs oft nur den Kandidaten, das ist kein Absenden
  if (event.key === 'Enter' && !event.isComposing && event.keyCode !== 229) {
    event.preventDefault();
    console.log('Nachricht gesendet:', chat.value);
    chat.value = '';
  }
});

chat.addEventListener('compositionend', (event) => {
  console.log('Kandidat bestätigt:', event.data);
});
Kandidat bestätigt: こんにちは Nachricht gesendet: こんにちは

Handler per on-Property setzen und wieder entfernen

const field = document.querySelector('textarea');

const onEnd = (event) => {
  console.log('Fertig:', event.data);
};

// Variante 1: addEventListener / removeEventListener
field.addEventListener('compositionend', onEnd);
field.removeEventListener('compositionend', onEnd);

// Variante 2: on-Property (wo unterstützt)
field.oncompositionend = onEnd;
field.oncompositionend = null; // entfernt den Handler

// Variante 3: mit AbortController
const controller = new AbortController();
field.addEventListener('compositionend', onEnd, { signal: controller.signal });
controller.abort();

// Wichtig · Fallstricke

  • Nicht abbrechbar: compositionend ist nicht cancelable. Wer die Eingabe blockieren will, braucht beforeinput, das ist aber während einer Komposition ebenfalls eingeschränkt.
  • Reihenfolge ist browserabhängig: Chrome und Firefox lösen nach compositionend kein weiteres input-Ereignis mit isComposing === false aus, Safari schickt dagegen compositionend vor dem letzten keydown. Daher die Logik sowohl in compositionend als auch in input (mit isComposing-Prüfung) unterbringen.
  • Enter bei IMEs: In Safari hat das keydown für die bestätigende Enter-Taste nach compositionend isComposing === false. Die zusätzliche Prüfung auf keyCode === 229 ist ein verbreiteter Workaround.
  • Abbruch: Bei Abbruch (Esc, Fokuswechsel) ist event.data meist leer. Das kann je nach IME aber auch anders sein. Zuverlässiger ist es, den aktuellen Wert von event.target.value zu lesen.
  • Nicht nur Asien: Komposition entsteht auch durch Tottasten (z. B. ^ + e = „ê“), Android-Tastaturen mit Wortvorschlägen und Diktierfunktionen. Auf Android laufen oft alle Eingaben über Kompositionsereignisse.
  • Ziel: Das Ereignis tritt nur an editierbaren Elementen auf (<input>, <textarea>, contenteditable) und bubbelt bis zum document.
  • Kompatibilität: addEventListener mit compositionend funktioniert in allen modernen Browsern. Das IDL-Attribut oncompositionend fehlt in einigen Browsern, deshalb addEventListener bevorzugen.