HTML onended Attribute

Beginner
⏱️ 5 min read
📚 Updated: Jun 2026
🎯 3 Examples
Media & Playback

Introduction

The onended attribute is an inline event handler that runs JavaScript when the ended event fires. That happens on <audio> and <video> when playback reaches the end of the media naturally. Use it to show a replay button, play the next track in a playlist, display a “Thanks for watching” message, or log analytics. It does not fire when the user pauses mid-playback (that is onpause) or when media is reset (that is onemptied). With the loop attribute enabled, ended typically does not fire because playback restarts automatically.

What You’ll Learn

01

Event handler

Inline JS.

02

ended

Playback done.

03

audio / video

Media elements.

04

Replay UI

Show replay btn.

05

addEventListener

Preferred way.

06

.onended

Property API.

Purpose of onended Attribute

The primary purpose of onended is to react when media playback completes. You might reveal a replay button, advance to the next song, show end-screen credits, or trigger completion tracking. It is a one-time event at the natural end of the timeline — unlike ontimeupdate, which fires continuously during playback.

Pair onended with playlist logic in JavaScript: when one clip finishes, load and play the next. For single clips, update UI to invite the user to replay or navigate elsewhere.

💡
Prefer addEventListener on the media element

Production code should use audio.addEventListener("ended", handler). Inline onended on <audio> or <video> works for learning but separates concerns less cleanly.

📝 Syntax

Set onended on audio or video, or assign element.onended:

onended.html
<script>
  function handleMediaEnd() {
    console.log("Playback finished.");
  }
</script>

<audio controls onended="handleMediaEnd()">
  <source src="song.mp3" type="audio/mpeg">
</audio>

Syntax Rules

  • Value is JavaScript code executed when the ended event fires.
  • Applies to <audio> and <video> media elements.
  • Fires when playback reaches the end — not on pause or seek.
  • JavaScript: media.onended = function() { … }.
  • Modern alternative: media.addEventListener("ended", handler).
  • Usually skipped when loop is enabled (media restarts).

💎 Values

The onended attribute accepts a string of JavaScript code:

  • onended="handleMediaEnd()" — Call a named function.
  • onended="showReplay()" — Inline statement.
  • JavaScript: video.onended = () => { … } assigns the handler.
onended-js.html
const video = document.getElementById("clip");

video.addEventListener("ended", () => {
  document.getElementById("replay-btn").hidden = false;
});

document.getElementById("replay-btn").addEventListener("click", () => {
  video.currentTime = 0;
  video.play();
  document.getElementById("replay-btn").hidden = true;
});

⚡ Quick Reference

Scenarioended fires?Notes
Playback reaches endYesPrimary use case
User pauses mid-clipNoUse onpause
loop attribute setUsually noMedia restarts
User seeks to end manuallyVariesMay fire if playback continues to end
Handler attributeonendedInline on media tag
Applicable elementsaudio, videoMedia elements only

Applicable Elements

TargetSupported?Notes
<audio>YesInline onended on audio
<video>YesEnd screens, replay buttons
<source>NoEvent fires on parent media element
<input>, <img>NoNot media playback events

onended vs onpause vs ontimeupdate

HandlerWhen it firesTypical use
onendedPlayback reaches the endReplay, next track, end screen
onpausePlayback paused (user or script)Save position, update UI
ontimeupdatecurrentTime changes during playProgress bar updates

Examples Gallery

Inline onended on audio, addEventListener on video, and a simple replay pattern.

👀 Live Preview

Play the audio to the end — status updates when ended fires:

Press play and listen to the end…

Example — Inline onended on audio

Run a function when playback completes:

inline-onended.html
<script>
  function handleMediaEnd() {
    console.log("Media playback has ended!");
  }
</script>

<audio controls onended="handleMediaEnd()">
  <source src="song.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>
Try It Yourself

How It Works

The browser fires ended on the audio element when playback completes. The inline onended attribute wires up the handler.

Dynamic Values with JavaScript

Attach the handler with addEventListener:

dynamic-onended.html
<script>
  document.getElementById("dynamicAudio").addEventListener("ended", function () {
    console.log("Custom ended event triggered!");
  });

  // Or property form:
  document.getElementById("dynamicAudio").onended = function () { /* … */ };
</script>
Try It Yourself

How It Works

Register the listener once at page load. When playback finishes, your completion logic runs once.

Example — Show replay button

Reveal a replay control when the video ends:

onended-replay.html
const video = document.getElementById("clip");
const replay = document.getElementById("replay");

video.addEventListener("ended", () => {
  replay.hidden = false;
});

replay.addEventListener("click", () => {
  video.currentTime = 0;
  video.play();
  replay.hidden = true;
});
Try It Yourself

How It Works

onended is the hook for post-playback UX — replay, autoplay next, or end-screen content.

♿ Accessibility

  • Announce completion — Use a live region when playback ends if custom controls replace native ones.
  • Make replay keyboard-accessible — Replay buttons need focus styles and Enter/Space support.
  • Avoid alert() on ended — Update visible status or show an in-page end screen instead.
  • Do not autoplay the next clip silently — Respect user preferences; offer a clear next action.
  • Captions through the end — Ensure subtitle tracks display through the final frame.

🧠 How onended Works

1

User plays media

Audio or video starts from currentTime.

play
2

Playback progresses

timeupdate fires during playback.

Progress
3

End reached

ended fires; onended runs.

Event
=

Post-playback actions

Replay, next track, or end screen.

Browser Support

The ended event and onended handler are supported in all modern browsers on <audio> and <video> elements — Chrome, Firefox, Safari, and Edge.

DOM Events · Fully supported

Universal onended support

All major browsers fire the underlying event and honor the onended handler attribute.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 9+ supported
Full support
Opera Fully supported
Full support
onended attribute 99% supported

Bottom line: Use onended confidently on media elements; prefer addEventListener in production code.

💡 Best Practices

✅ Do

  • Show replay or next-track UI when ended fires
  • Use addEventListener("ended", …) in production code
  • Test with and without the loop attribute
  • Update progress UI one final time before end-screen logic
  • Keep end-of-playback actions accessible and visible

❌ Don’t

  • Use alert() when media finishes
  • Confuse ended with pause or emptied
  • Assume ended fires when loop is enabled
  • Attach handlers to <source> instead of the media element
  • Autoplay the next video without user consent

Conclusion

The onended attribute runs JavaScript when audio or video playback reaches its natural end — the right hook for replay buttons, playlists, and completion messages.

Prefer addEventListener("ended", …), distinguish ended from pause and timeupdate events, and remember that looping media usually skips ended between repeats.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about onended

Bookmark these before building your next media player.

5
Core concepts
🌐 02

audio / video

Media only.

Scope
🔀 03

Replay UI

Common pattern.

UX
📝 04

addEventListener

Preferred.

Modern
🔀 05

Not loop

loop skips end.

Compare

❓ Frequently Asked Questions

It runs JavaScript when the ended event fires — when playback reaches the end of the media.
<audio> and <video>. Attach handlers to the media element, not individual <source> tags.
No. Pausing fires pause. ended fires only when playback completes to the end.
Usually not — the browser restarts playback automatically, so ended typically does not fire between loops.
addEventListener("ended", handler) is preferred for production. Inline onended is fine for tutorials and quick demos.
Yes in all modern browsers on audio and video elements.

Handle playback completion like a pro

Practice the onended attribute with replay and playlist examples in the Try It editor.

Try onended demo →

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