Signatur
Beschreibung
Das Ereignis animationiteration wird an einem Element ausgelöst, sobald ein Durchlauf einer CSS-Animation (@keyframes) abgeschlossen ist und unmittelbar der nächste beginnt. Es gehört zur Familie der CSS-Animations-Ereignisse zusammen mit animationstart, animationend und animationcancel. Das Ereignis-Objekt ist ein AnimationEvent mit den Eigenschaften animationName, elapsedTime und pseudoElement.
Registrieren lässt sich der Handler per element.addEventListener("animationiteration", handler) oder über die Eigenschaft element.onanimationiteration = handler. Das Ereignis steigt im DOM auf (bubbles), ist aber nicht abbrechbar – man kann also einen Listener am Elternelement registrieren und über event.target sowie event.animationName unterscheiden, welche Animation gemeint ist.
Typische Einsatzfälle sind Zähler für Durchläufe, das Synchronisieren von JavaScript-Logik mit wiederholenden Animationen (z. B. Wechsel des Inhalts nach jeder Runde eines Karussells oder Tickers) oder das gezielte Stoppen einer endlosen Animation nach einer bestimmten Anzahl von Wiederholungen bzw. am Ende eines Durchlaufs, damit sie nicht abrupt mitten in der Bewegung abbricht.
Wichtig: Nach dem letzten Durchlauf wird kein animationiteration, sondern animationend ausgelöst. Bei animation-iteration-count: 1 feuert das Ereignis daher nie.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp: "animationiteration". |
|
| $handler Pflicht | (event: AnimationEvent) => void | Callback, das ein AnimationEvent mit animationName, elapsedTime (Sekunden seit Animationsbeginn, ohne animation-delay) und pseudoElement erhält. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, capture, passive oder signal (AbortSignal zum Entfernen). |
Beispiele
Durchläufe einer Puls-Animation zählen
// CSS: .pulse { animation: pulse 1s ease-in-out infinite; }
// @keyframes pulse { 50% { transform: scale(1.2); } }
const button = document.querySelector('.pulse');
let runden = 0;
button.addEventListener('animationiteration', (event) => {
runden += 1;
console.log(`${event.animationName}: Runde ${runden} beendet nach ${event.elapsedTime}s`);
});
Endlose Animation nach 3 Runden sauber stoppen und Listener entfernen
const spinner = document.querySelector('.spinner');
let count = 0;
const onIteration = () => {
count += 1;
if (count >= 3) {
// Am Rundenende stoppen – kein abruptes Springen mitten in der Bewegung
spinner.style.animationPlayState = 'paused';
spinner.removeEventListener('animationiteration', onIteration);
console.log('Spinner nach 3 Runden angehalten');
}
};
spinner.addEventListener('animationiteration', onIteration);
News-Ticker: Text per on-Property nach jeder Runde wechseln
const ticker = document.querySelector('#ticker');
const meldungen = ['Neue Version 2.0 erschienen', 'Wartung am Sonntag', 'Jetzt Newsletter abonnieren'];
let index = 0;
ticker.textContent = meldungen[index];
ticker.onanimationiteration = (event) => {
if (event.animationName !== 'scroll-left') return;
index = (index + 1) % meldungen.length;
ticker.textContent = meldungen[index];
};
// Später deaktivieren:
// ticker.onanimationiteration = null;
Ereignisdelegation am Container
const liste = document.querySelector('#karten');
liste.addEventListener('animationiteration', ({ target, animationName, pseudoElement }) => {
console.log(`${target.id || target.tagName} – ${animationName}${pseudoElement ? ' (' + pseudoElement + ')' : ''}`);
});
// Wichtig · Fallstricke
- Kein Ereignis beim letzten Durchlauf: Nach der finalen Iteration kommt
animationend, nichtanimationiteration. Bei nur einem Durchlauf feuert es gar nicht. - Hintergrund-Tabs und Drosselung: In inaktiven Tabs können Animationen pausiert oder gedrosselt werden; mehrere Iterationen können dann ausbleiben oder zusammengefasst werden. Nicht für exakte Zeitmessung verwenden.
elapsedTimeist in Sekunden angegeben und enthält nicht die Zeit vonanimation-delay; bei negativem Delay kann sie entsprechend verschoben sein.- Wird die Animation per
animation: noneoderdisplay: noneentfernt, feuert stattdessen ggf.animationcancel. - Nutzer mit
prefers-reduced-motion: reducekönnen Animationen per CSS abgeschaltet haben – Logik sollte nicht zwingend vom Ereignis abhängen. - Nur CSS-Animationen lösen das Ereignis aus; Animationen über die Web Animations API (
element.animate()) nicht. Präfixierte VariantewebkitAnimationIterationnur für sehr alte WebKit-Browser relevant.