Signatur
Beschreibung
Das Ereignis animationstart wird ausgelöst, sobald eine per CSS definierte Animation (@keyframes plus animation-Eigenschaft) auf einem Element beginnt. Ist ein positiver animation-delay gesetzt, feuert das Ereignis erst nach Ablauf dieser Verzögerung. Bei einem negativen Delay feuert es sofort, und elapsedTime enthält dann den übersprungenen Anteil.
Registriert wird das Ereignis mit addEventListener("animationstart", handler) oder über die Eigenschaft onanimationstart. Der Handler erhält ein AnimationEvent mit den Eigenschaften animationName (Name der @keyframes-Regel), elapsedTime (Sekunden seit Start ohne Pausen) und pseudoElement (z. B. "::before" oder ein leerer String).
Typische Einsatzfälle: Zustände synchronisieren (etwa Buttons während einer Animation sperren), Messwerte oder Analysedaten erfassen, Ton und Animation gleichzeitig starten oder Elemente erkennen, die neu ins DOM eingefügt wurden. Für den letzten Fall gibt es einen bekannten Trick: Man vergibt eine unsichtbare Animation per CSS-Selektor.
Das Ereignis steigt im DOM auf (bubbles) und lässt sich nicht abbrechen. Deshalb kann man es per Ereignis-Delegation auch an einem übergeordneten Element abfangen. Mit event.target und animationName unterscheidet man dann, welche Animation gerade gestartet ist.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "animationstart". |
|
| $handler Pflicht | (event: AnimationEvent) => void | Callback, der ein AnimationEvent erhält, mit animationName, elapsedTime und pseudoElement. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, capture, passive oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein AnimationEvent.Beispiele
Start einer Animation per addEventListener erkennen
// CSS: .box { animation: slideIn 1s ease-out 0.5s; }
// @keyframes slideIn { from { transform: translateX(-100%); } to { transform: none; } }
const box = document.querySelector('.box');
box.addEventListener('animationstart', (event) => {
console.log(`Animation "${event.animationName}" gestartet nach ${event.elapsedTime}s`);
box.setAttribute('aria-busy', 'true');
});
box.addEventListener('animationend', () => {
box.removeAttribute('aria-busy');
});
on-Eigenschaft und removeEventListener
const banner = document.querySelector('#banner');
// Variante 1: on-Eigenschaft (nur ein Handler möglich)
banner.onanimationstart = (e) => console.log('Start:', e.animationName);
// Variante 2: benannter Handler, der sich wieder entfernen lässt
const logStart = (e) => {
console.log('Einmalig protokolliert:', e.animationName);
banner.removeEventListener('animationstart', logStart);
};
banner.addEventListener('animationstart', logStart);
// Animation auslösen
banner.classList.add('pulse');
Neu eingefügte DOM-Elemente per Animations-Trick erkennen
// CSS:
// @keyframes nodeInserted { from { opacity: 0.99; } to { opacity: 1; } }
// .todo-item { animation: nodeInserted 1ms; }
const list = document.querySelector('#todo-list');
// Delegation: animationstart steigt auf
list.addEventListener('animationstart', (e) => {
if (e.animationName !== 'nodeInserted') return;
console.log('Neues Element:', e.target.textContent);
e.target.classList.add('initialisiert');
});
const li = document.createElement('li');
li.className = 'todo-item';
li.textContent = 'Milch kaufen';
list.append(li);
// Wichtig · Fallstricke
- Kein Ereignis ohne echte Animation: Bei
animation-duration: 0sfeuern trotzdemanimationstartundanimationend. Ist dagegendisplay: nonegesetzt oder fehlt die@keyframes-Regel bzw. ist ihr Name falsch geschrieben, feuert gar nichts. - Nutzer mit reduzierter Bewegung: Wenn die Animation per
@media (prefers-reduced-motion: reduce)abgeschaltet wird, bleibt das Ereignis aus. Logik, die sich darauf verlässt, braucht daher einen Ausweichpfad. - Timing: Wird der Handler erst registriert, nachdem die Animation schon begonnen hat, verpasst er das Ereignis. Also zuerst den Listener registrieren und erst danach die Klasse bzw. Animation setzen.
- Neustart: Dieselbe Klasse erneut zu setzen, startet die Animation nicht neu. Man muss sie entfernen, einen Reflow erzwingen (z. B.
el.offsetWidth) und sie dann wieder hinzufügen. Wiederholungen durchanimation-iteration-countlösenanimationiterationaus, nichtanimationstart. - Pseudo-Elemente: Animationen auf
::beforeund::afterfeuern am Elternelement. Welches Pseudo-Element gemeint ist, steht inevent.pseudoElement. - Kompatibilität: Wird in allen modernen Browsern unterstützt. Sehr alte WebKit-Versionen kannten nur
webkitAnimationStart. CSS-Transitions lösen dieses Ereignis nicht aus, dafür gibt estransitionstart. Auch Animationen über die Web Animations API (element.animate()) lösen es nicht aus.