JavaScript Element animationiteration Event

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
DOM event
Instance event

What You’ll Learn

The animationiteration event fires when one CSS Animation loop ends and the next begins. Learn addEventListener vs onanimationiteration, how to count loops, why single-iteration animations never fire it, and how it fits next to animationend—with five examples and try-it labs.

01

Kind

Instance event

02

Type

AnimationEvent

03

When

Loop boundary

04

Handler

onanimationiteration

05

Needs

count > 1

06

Status

Baseline widely available

Introduction

CSS animations can repeat with animation-iteration-count. Each time one loop finishes and the next starts, the browser fires animationiteration. That is perfect for counters, progress labels, or syncing side effects per loop.

MDN: this event does not occur at the same time as animationend, and therefore does not occur for animations with an animation-iteration-count of 1.

💡
Beginner tip

Prefer addEventListener("animationiteration", ...) so you can attach multiple handlers and remove them cleanly. Use a counter variable if you need “how many loops so far.”

Understanding animationiteration

An instance event on elements whose CSS Animation repeats. It answers: “Did another loop just begin after the previous one ended?”

  • Fires between iterations (end of one loop → start of the next).
  • Does not fire for animation-iteration-count: 1.
  • Does not replace animationend on the final loop.
  • AnimationEvent — includes animationName, elapsedTime, pseudoElement.
  • Baseline Widely available on MDN (since December 2019).

📝 Syntax

Use the event name with addEventListener, or set the handler property:

JavaScript
addEventListener("animationiteration", (event) => { });

onanimationiteration = (event) => { };

Event type

An AnimationEvent (inherits from Event).

Event properties

PropertyMeaning
animationNameThe animation-name that generated the animation
elapsedTimeSeconds the animation had been running when this event fired (paused time excluded)
pseudoElement:: name if animated on a pseudo-element; otherwise ""

⚖️ Animation lifecycle events

EventWhen it firesTypical use
animationstartAnimation beginsMark UI as “playing”
animationiterationEach loop ends and the next beginsCount loops / per-loop effects
animationendEntire animation finishesCleanup after success
animationcancelAnimation aborts earlyCleanup after interrupt

Example: with animation-iteration-count: 3 you typically get animationstart, then animationiteration twice, then animationend.

⚡ Quick Reference

GoalCode / note
Listenel.addEventListener("animationiteration", fn)
Handler propertyel.onanimationiteration = fn
Count loopsIncrement a variable inside the handler
Need the event?Set animation-iteration-count to 2+ or infinite
count: 1No animationiteration — only start/end
Read nameevent.animationName
MDN statusBaseline Widely available (Dec 2019)

🔍 At a Glance

Four facts to remember about animationiteration.

Event type
AnimationEvent

Name + time

Means
next loop

Between iterations

count: 1
no fire

No next loop

Baseline
yes

Widely available

Examples Gallery

Examples follow MDN Element: animationiteration event. Try It Yourself labs use animation-iteration-count greater than one so the event can fire.

📚 Getting Started

Register handlers the MDN ways and count loops.

Example 1 — addEventListener("animationiteration")

MDN: keep track of how many iterations have completed.

JavaScript
const animated = document.querySelector(".animated");

let iterationCount = 0;

animated.addEventListener("animationiteration", () => {
  iterationCount++;
  console.log(`Animation iteration count: ${iterationCount}`);
});

// Requires animation-iteration-count of 2+ (or infinite).
Try It Yourself

How It Works

Each time a loop finishes and another starts, your counter increases. The final loop ends with animationend, not another animationiteration.

Example 2 — onanimationiteration Property

MDN’s alternate style using the event handler property.

JavaScript
const animated = document.querySelector(".animated");

let iterationCount = 0;

animated.onanimationiteration = () => {
  iterationCount++;
  console.log(`Animation iteration count: ${iterationCount}`);
};

// Assigning again replaces the previous onanimationiteration handler.
Try It Yourself

How It Works

Same event, different registration API. Prefer addEventListener when you need more than one handler.

📈 Details, One-Shot & Lifecycle

Read AnimationEvent fields, prove count:1 skips the event, watch the full set.

Example 3 — Read animationName and elapsedTime

Inspect AnimationEvent properties on each loop boundary.

JavaScript
const box = document.getElementById("box");

box.addEventListener("animationiteration", (event) => {
  console.log("name:", event.animationName);
  console.log("elapsedTime:", event.elapsedTime);
  console.log("pseudoElement:", JSON.stringify(event.pseudoElement));
});

box.classList.add("pulse"); // CSS: iteration-count 3
Try It Yourself

How It Works

elapsedTime grows with each boundary because it measures total running time so far (excluding pauses), not just the latest loop.

Example 4 — Why count: 1 Never Fires It

Compare a one-shot animation (no iteration event) with a two-loop animation.

JavaScript
const once = document.getElementById("once");
const twice = document.getElementById("twice");

function wire(el, label) {
  el.addEventListener("animationiteration", () => {
    console.log(label + ": iteration");
  });
  el.addEventListener("animationend", () => {
    console.log(label + ": end");
  });
}

wire(once, "count1");
wire(twice, "count2");

once.classList.add("run-once");   // iteration-count: 1
twice.classList.add("run-twice"); // iteration-count: 2
Try It Yourself

How It Works

A single cycle has no “next iteration,” so MDN’s rule applies: no animationiteration. Two cycles produce one boundary event, then animationend.

Example 5 — Full Lifecycle Log

Inspired by MDN’s live example: log start, iteration, end, and cancel together.

JavaScript
const el = document.querySelector("p.animation");
const log = document.getElementById("log");
const btn = document.getElementById("toggle");
let iterations = 0;

function append(msg) {
  log.textContent += msg + " ";
}

el.addEventListener("animationstart", () => append("start"));
el.addEventListener("animationiteration", () => {
  iterations += 1;
  append("iteration:" + iterations);
});
el.addEventListener("animationend", () => {
  append("end");
  el.classList.remove("active");
  btn.textContent = "Activate animation";
});
el.addEventListener("animationcancel", () => append("canceled"));

btn.addEventListener("click", () => {
  el.classList.toggle("active");
  log.textContent = "";
  iterations = 0;
  const on = el.classList.contains("active");
  btn.textContent = on ? "Cancel animation" : "Activate animation";
});
Try It Yourself

How It Works

With two iterations you see one animationiteration between start and end. Canceling mid-run skips the remaining events and may log canceled instead.

🚀 Common Use Cases

  • Showing “loop 2 of 5” style progress during a repeating animation.
  • Triggering a sound or haptic cue on each cycle.
  • Rotating captions or tips between loops of a hero animation.
  • Debugging whether animation-iteration-count is behaving as expected.
  • Teaching the full CSS animation event set next to animationend.

🔧 How It Works

1

Animation starts

animationstart fires for the first loop.

Start
2

A loop finishes

Another iteration is still scheduled.

Boundary
3

animationiteration fires

Then the next loop begins immediately.

Event
4

Last loop ends with animationend

No iteration event on that final boundary.

📝 Notes

  • MDN: Baseline Widely available (since December 2019).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Does not fire with animation-iteration-count: 1.
  • Does not fire together with animationend on the final iteration.
  • Related learning: animationend, animationcancel, addEventListener(), JavaScript hub.

Universal Browser Support

animationiteration is marked Baseline Widely available on MDN (since December 2019). Logos use the shared browser-image-sprite.png sprite from this project. Pair it with animationend for complete loop handling.

Baseline · Widely available

Element animationiteration

Works across modern desktop and mobile browsers for multi-iteration CSS animations.

100% Widely available
Google Chrome Supported · Desktop & Android
Full support
Mozilla Firefox Supported · Desktop & Android
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Opera Supported · Modern versions
Full support
Internet Explorer Legacy support with prefixes in older IE
Partial
animationiteration Baseline

Bottom line: Use when animation-iteration-count is greater than one (or infinite). One-shot animations will not fire this event.

Conclusion

animationiteration is the loop-boundary signal for repeating CSS Animations. Count iterations with a simple variable, remember single-cycle animations skip this event, and finish cleanup on animationend.

Continue with animationstart, addEventListener(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Prefer addEventListener("animationiteration", ...)
  • Set animation-iteration-count to 2+ when you need this event
  • Keep your own counter for “loops completed”
  • Also listen for animationend for final cleanup
  • Filter with event.animationName when multiple animations share a node

❌ Don’t

  • Expect the event from animation-iteration-count: 1
  • Confuse it with animationend on the last loop
  • Assume it fires together with animationend
  • Forget infinite animations never reach animationend
  • Overwrite onanimationiteration if you need multiple listeners

Key Takeaways

Knowledge Unlocked

Five things to remember about animationiteration

A loop just finished—and another one is starting.

5
Core concepts
🎬 02

AnimationEvent

name + time

API
🚫 03

count: 1

never fires

Rule
📈 04

Count loops

own counter

Pattern
🎯 05

Baseline

widely available

Compat

❓ Frequently Asked Questions

It fires when one iteration of a CSS Animation ends and another iteration begins. It does not fire at the same time as animationend, and it does not fire for animations whose animation-iteration-count is one.
No. MDN marks Element animationiteration as Baseline Widely available (since December 2019). It is not Deprecated, Experimental, or Non-standard.
An AnimationEvent. Useful read-only properties include animationName, elapsedTime, and pseudoElement.
Use element.addEventListener("animationiteration", handler) or set element.onanimationiteration = handler. Prefer addEventListener when you need multiple handlers or easy removal.
Because there is no "next" iteration after the only cycle. With animation-iteration-count: 1, you get animationstart and then animationend — no animationiteration in between.
animationiteration marks the boundary between loops while the animation continues. animationend fires once when the entire animation (including the last iteration) has finished.
Did you know?

For an animation with animation-iteration-count: n (where n is a finite integer greater than 1), you typically get n - 1 animationiteration events, then one animationend.

Next: animationstart

Learn when a CSS animation begins—including delay timing.

animationstart →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful