Signatur
Beschreibung
Das Ereignis animationend wird ausgelöst, sobald eine per CSS definierte Animation (@keyframes + animation-Eigenschaft) alle Durchläufe beendet hat. Du registrierst es über element.addEventListener("animationend", handler) oder über die Eigenschaft element.onanimationend. Das Ereignis steigt im DOM auf (Bubbling) und lässt sich nicht abbrechen.
Typische Einsatzfälle sind das Aufräumen nach einer Animation (Element entfernen, Klasse zurücksetzen), das Verketten von Animationen oder das Aktualisieren des Zustands, sobald z. B. ein Ausblend-Effekt fertig ist. So hältst du JavaScript-Logik und CSS-Timing sauber synchron, ohne feste setTimeout-Werte zu duplizieren.
Der Handler erhält ein AnimationEvent mit den Eigenschaften animationName (Name der @keyframes-Regel), elapsedTime (verstrichene Zeit in Sekunden, ohne Verzögerung) und pseudoElement (z. B. "::before" oder leerer String). Da das Ereignis aufsteigt, empfängt ein Elternelement auch die Ereignisse animierter Kindelemente – prüfe daher bei Bedarf event.target und event.animationName.
Verwandte Ereignisse sind animationstart, animationiteration (nach jedem Durchlauf außer dem letzten) und animationcancel (wenn die Animation vorzeitig abgebrochen wird).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier "animationend". |
|
| $handler Pflicht | (event: AnimationEvent) => void | Callback, der beim Ende der Animation aufgerufen wird und ein AnimationEvent erhält. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { once: true }, um den Listener nach dem ersten Auslösen automatisch zu entfernen, oder signal für einen AbortController. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein AnimationEvent mit animationName, elapsedTime und pseudoElement.Beispiele
Element nach dem Ausblenden entfernen
// CSS: .fade-out { animation: fadeOut 0.4s ease forwards; }
// @keyframes fadeOut { to { opacity: 0; } }
const toast = document.querySelector('.toast');
toast.addEventListener('animationend', (event) => {
console.log(`Animation "${event.animationName}" nach ${event.elapsedTime}s beendet`);
toast.remove();
}, { once: true });
toast.classList.add('fade-out');
Animation per Klasse erneut abspielbar machen
// CSS: .shake { animation: shake 0.5s; }
const button = document.querySelector('#submit');
const onShakeEnd = () => {
button.classList.remove('shake');
};
button.addEventListener('animationend', onShakeEnd);
const showError = () => button.classList.add('shake');
showError();
// Später, wenn nicht mehr benötigt:
// button.removeEventListener('animationend', onShakeEnd);
On-Property und Filterung nach Animationsname
const card = document.querySelector('.card');
card.onanimationend = (event) => {
// Bubbling: Ereignisse von Kindelementen ignorieren
if (event.target !== card) return;
if (event.animationName === 'slideIn') {
card.classList.add('is-visible');
console.log('Karte eingeblendet');
}
};
// Handler wieder entfernen
// card.onanimationend = null;
Animation als Promise abwarten
const waitForAnimation = (el, className) => new Promise((resolve) => {
const done = (event) => {
if (event.target !== el) return;
el.removeEventListener('animationend', done);
el.removeEventListener('animationcancel', done);
resolve(event.type);
};
el.addEventListener('animationend', done);
el.addEventListener('animationcancel', done);
el.classList.add(className);
});
const modal = document.querySelector('.modal');
const result = await waitForAnimation(modal, 'zoom-out');
console.log(result);
modal.hidden = true;
// Wichtig · Fallstricke
- Wird nicht immer ausgelöst: Bei
animation-iteration-count: infinite, wenn das Element entfernt wird,display: noneerhält oder die Animation-Klasse vorher entfernt wird, feuertanimationendnicht. Im Abbruchfall kommt stattdessenanimationcancel(nicht in allen älteren Browsern). Plane für kritische Logik einen Fallback ein. - Bubbling: Das Ereignis steigt auf – Animationen von Kindelementen lösen auch Listener am Elternelement aus. Prüfe
event.targetbzw.event.animationName. - Mehrere Animationen: Bei mehreren Animationen in
animationfeuert das Ereignis einmal pro Animation. - Erneut abspielen: Dieselbe Klasse erneut hinzufügen startet die Animation nicht neu – die Klasse muss vorher (z. B. im
animationend-Handler) entfernt werden. - Nicht für Übergänge: Für CSS-
transitionisttransitionendzuständig; für Web-Animations-API-Animationen nutzeanimation.finishedbzw.onfinish. - prefers-reduced-motion: Wird die Animation per Media Query deaktiviert (
animation: none), feuert kein Ereignis – eine Logik, die darauf wartet, bleibt hängen. - Kompatibilität: In allen modernen Browsern ohne Präfix verfügbar; sehr alte WebKit-Versionen benötigten
webkitAnimationEnd.