Start · Sprachen · JavaScript · Referenz · Animation: finish

Animation: finish

Ereignis

Wird ausgelöst, wenn eine <code>Animation</code> fertig abgespielt ist – entweder regulär oder durch Aufruf von <code>Animation.finish()</code>.

seit JavaScript Baseline: alle modernen Browser (seit 2020) Kategorie: webapi

Signatur

animation.addEventListener("finish", handler)

Beschreibung

Das finish-Ereignis gehört zum Animation-Interface der Web Animations API. Es wird ausgelöst, sobald die Animation in den Wiedergabezustand "finished" wechselt. Das passiert, wenn die Animation ihr natürliches Ende erreicht (bzw. bei negativer Abspielrate den Anfang), oder wenn Animation.finish() aufgerufen wird, um sofort ans Ende zu springen.

Du kannst den Handler entweder mit animation.addEventListener("finish", handler) oder über die Eigenschaft animation.onfinish = handler registrieren. Der Handler bekommt ein AnimationPlaybackEvent mit den Eigenschaften currentTime und timelineTime.

Typische Einsatzfälle sind Aufräumarbeiten nach einer Animation: Elemente aus dem DOM entfernen, Klassen setzen, den Endzustand dauerhaft übernehmen (z. B. per commitStyles()) oder mehrere Animationen hintereinander ausführen. Oft ist das Promise animation.finished die bessere Wahl, weil es sich gut mit async/await kombinieren lässt.

Wichtig: Das Ereignis wird nicht ausgelöst, wenn die Animation abgebrochen wird (cancel()) – dafür gibt es das Ereignis cancel. Bei Endlosanimationen (iterations: Infinity) tritt es nie von selbst ein.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier immer "finish".
$handler Pflicht (event: AnimationPlaybackEvent) => void Callback, der beim Ende der Animation aufgerufen wird. Bekommt ein AnimationPlaybackEvent mit currentTime und timelineTime.
$options boolean|AddEventListenerOptions false Optionale Listener-Optionen, z. B. { once: true } oder { signal }.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein AnimationPlaybackEvent.

Beispiele

Element nach Ausblend-Animation entfernen (addEventListener)

const toast = document.querySelector('.toast');

const fadeOut = toast.animate(
  [{ opacity: 1 }, { opacity: 0 }],
  { duration: 500, easing: 'ease-out' }
);

fadeOut.addEventListener('finish', (event) => {
  console.log('Fertig bei', event.currentTime, 'ms');
  toast.remove();
}, { once: true });
Fertig bei 500 ms

Handler über onfinish setzen und wieder entfernen

const box = document.querySelector('#box');
const slide = box.animate(
  [{ transform: 'translateX(0)' }, { transform: 'translateX(300px)' }],
  { duration: 1000, fill: 'forwards' }
);

slide.onfinish = () => {
  slide.commitStyles(); // Endzustand ins style-Attribut schreiben
  slide.cancel();       // Animation freigeben
  console.log('Position übernommen:', box.style.transform);
};

// Handler bei Bedarf wieder entfernen:
// slide.onfinish = null;
Position übernommen: translateX(300px)

finish() löst das Ereignis sofort aus

const spinner = document.querySelector('.spinner');
const spin = spinner.animate(
  [{ transform: 'rotate(0deg)' }, { transform: 'rotate(360deg)' }],
  { duration: 2000, iterations: 3 }
);

const onFinish = () => console.log('Spinner beendet, Status:', spin.playState);
spin.addEventListener('finish', onFinish);

// Daten sind schon da – Animation sofort ans Ende springen lassen
setTimeout(() => spin.finish(), 300);

// Später Listener aufräumen
setTimeout(() => spin.removeEventListener('finish', onFinish), 1000);
Spinner beendet, Status: finished

Alternative: Promise animation.finished mit await

const runSequence = async (el) => {
  await el.animate([{ opacity: 0 }, { opacity: 1 }], 400).finished;
  await el.animate([{ transform: 'scale(1)' }, { transform: 'scale(1.2)' }], 300).finished;
  console.log('Sequenz abgeschlossen');
};

runSequence(document.querySelector('.card'));
Sequenz abgeschlossen

// Wichtig · Fallstricke

  • Kein finish bei cancel(): Wird die Animation abgebrochen, feuert stattdessen cancel. Das Promise finished wird dann mit einem AbortError abgelehnt – also mit try/catch absichern.
  • Endlosanimationen (iterations: Infinity) lösen finish nie von selbst aus. finish() wirft dort einen InvalidStateError.
  • Asynchrone Zustellung: Das Ereignis wird in eine Warteschlange gestellt und nicht synchron im Aufruf von finish() ausgelöst. Wird die Animation vorher neu gestartet oder zurückgespult, kommt das Ereignis unter Umständen gar nicht an.
  • Mehrfaches Auslösen: Spielst du eine fertige Animation erneut ab (play(), reverse()), feuert finish bei jedem Ende wieder. Mit { once: true } verhinderst du doppelte Handler-Aufrufe.
  • fill: 'forwards' hält die Animation weiter aktiv und verbraucht Ressourcen. Besser im finish-Handler commitStyles() und dann cancel() aufrufen.
  • Kompatibilität: Wird in Chrome, Edge, Firefox und Safari (ab 13.1) unterstützt. Für CSS-Animationen und -Übergänge gibt es auf dem Element die eigenen Ereignisse animationend und transitionend.