Signatur
Beschreibung
Das Ereignis animationcancel tritt auf, wenn eine per CSS-Eigenschaft animation gestartete Animation abbricht. Das passiert zum Beispiel, wenn der animation-name entfernt oder geändert wird, das Element display: none bekommt (auch über ein Elternelement) oder das Element aus dem DOM entfernt wird. In diesen Fällen feuert kein animationend.
Das Ereignis ist nützlich, um Aufräumarbeiten sicher zu erledigen. Wer z. B. beim Start einer Animation eine Klasse setzt, Knöpfe sperrt oder einen Zustand merkt, muss das auch im Abbruchfall zurücksetzen. Deshalb hört man meist auf animationend und animationcancel zugleich.
Registrieren kann man den Handler mit addEventListener("animationcancel", handler) oder über die Eigenschaft element.onanimationcancel. Der Handler bekommt ein AnimationEvent mit animationName, elapsedTime (die aktive Laufzeit in Sekunden bis zum Abbruch) und pseudoElement. Das Ereignis steigt im DOM auf (Bubbling) und lässt sich nicht abbrechen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "animationcancel". |
|
| $handler Pflicht | (event: AnimationEvent) => void | Callback-Funktion, die ein AnimationEvent mit animationName, elapsedTime und pseudoElement bekommt. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, capture, passive oder signal (zum Entfernen über einen AbortController). |
Rückgabewert
addEventListener hat keinen Rückgabewert (undefined).Beispiele
Abbruch per addEventListener erkennen
// CSS: .pulse { animation: pulse 2s ease-in-out; }
const box = document.querySelector('.box');
box.addEventListener('animationcancel', (event) => {
console.log(`Abgebrochen: ${event.animationName} nach ${event.elapsedTime.toFixed(2)}s`);
});
box.classList.add('pulse');
// Nach 500 ms Animation entfernen → animationcancel feuert
setTimeout(() => {
box.classList.remove('pulse');
}, 500);
Aufräumen bei Ende UND Abbruch
const button = document.querySelector('#save');
const icon = button.querySelector('.spinner');
const resetUi = (event) => {
button.disabled = false;
icon.classList.remove('spin');
console.log(`${event.type}: UI zurückgesetzt`);
};
button.addEventListener('click', () => {
button.disabled = true;
icon.classList.add('spin');
// Beide Fälle behandeln, jeweils nur einmal
const controller = new AbortController();
const handler = (e) => { resetUi(e); controller.abort(); };
icon.addEventListener('animationend', handler, { signal: controller.signal });
icon.addEventListener('animationcancel', handler, { signal: controller.signal });
});
on-Property und Entfernen des Listeners
const toast = document.querySelector('.toast');
// Variante 1: on-Property
toast.onanimationcancel = (event) => {
console.log('Toast-Animation abgebrochen:', event.animationName);
};
// Variante 2: benannter Listener, später entfernbar
const onCancel = (event) => console.log('Listener:', event.animationName);
toast.addEventListener('animationcancel', onCancel);
toast.classList.add('slide-in');
// display: none bricht die Animation ab
toast.style.display = 'none';
// Aufräumen
toast.removeEventListener('animationcancel', onCancel);
toast.onanimationcancel = null;
// Wichtig · Fallstricke
- Kein Ersatz für
animationend: Pro Animationsdurchlauf feuert nur eines der beiden Ereignisse. Für zuverlässiges Aufräumen auf beide hören. - Element aus dem DOM entfernt: Die Spezifikation sieht ein Ereignis vor, aber das Verhalten ist nicht in allen Browsern gleich, und ein abgehängtes Element lässt das Ereignis nicht bis zum
documentaufsteigen. Den Listener deshalb direkt am Element registrieren. - Nur für CSS-Animationen: Animationen über die Web Animations API (
element.animate()) lösenanimationcancelnicht aus. Dort nutzt manAnimation.oncancelbzw. dascancel-Ereignis amAnimation-Objekt. Für CSS-Transitions gibt estransitioncancel. - Bubbling: Das Ereignis steigt auf. Ein Listener am Elternelement fängt also auch Abbrüche von Kindanimationen ab. Bei Bedarf mit
event.targetoderevent.animationNamefiltern. - Kompatibilität: Firefox kennt das Ereignis seit Version 54, Safari seit 13.1, Chromium-Browser erst seit Version 83. In sehr alten Browsern fehlt es ganz, dort sollte man zusätzlich einen Timeout als Rückfallebene einplanen.