HTML oncanplay Attribute

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

Introduction

The oncanplay attribute is an inline event handler that runs JavaScript when the canplay event fires. That happens on <audio> and <video> when the browser has buffered enough data that playback can start. Use it to hide loading spinners, enable custom play buttons, or log readiness. It does not mean the entire file is downloaded—only that playback can begin. For uninterrupted playback through the end, see oncanplaythrough.

What You’ll Learn

01

Event handler

Inline JS.

02

canplay

Media event.

03

audio / video

Media elements.

04

+ canplaythrough

Start vs full buffer.

05

addEventListener

Preferred way.

06

.oncanplay

Property API.

Purpose of oncanplay Attribute

The primary purpose of oncanplay is to react when media becomes ready to start. You might hide a “Loading…” overlay, enable a custom play button, start autoplay (where allowed), or sync UI with buffer state. The event is part of the media loading lifecycle alongside loadedmetadata, loadeddata, and canplaythrough.

The old reference used alert() in demos—avoid that in real apps. Status text or UI updates are clearer. Also note: canplay can fire multiple times if the user seeks or network conditions cause re-buffering.

💡
Prefer addEventListener on the media element

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

📝 Syntax

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

oncanplay.html
<script>

  function handleCanPlay() {

    console.log("Media can start playing.");

  }

</script>



<audio controls oncanplay="handleCanPlay()">

  <source src="song.mp3" type="audio/mpeg">

</audio>

Syntax Rules

  • Value is JavaScript code executed when the canplay event fires.
  • Applies to <audio> and <video> media elements.
  • Fires when enough data is buffered to begin playback.
  • JavaScript: media.oncanplay = function() { … }.
  • Modern alternative: media.addEventListener("canplay", handler).
  • May fire again after seeking or re-buffering.

💎 Values

The oncanplay attribute accepts a string of JavaScript code:

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

video.addEventListener("canplay", () => {

  document.getElementById("loader").hidden = true;

});

video.addEventListener("waiting", () => {

  document.getElementById("loader").hidden = false;

});

⚡ Quick Reference

EventWhen it firesHandler
canplayEnough data to startoncanplay
canplaythroughCan play to end (estimate)oncanplaythrough
loadeddataFirst frame readyonloadeddata
Hide loaderIn canplay handlerCommon pattern
Re-bufferwaiting then canplay againMay repeat

Applicable Elements

TargetSupported?Notes
<audio>YesInline oncanplay on audio
<video>YesMost common use
<source>NoEvent fires on parent media element
<input>, <img>NoNot media canplay events

oncanplay vs oncanplaythrough vs onloadeddata

HandlerWhen it firesTypical use
onloadeddataFirst frame of media availableShow poster / first frame
oncanplayEnough buffered to startEnable play button, hide loader
oncanplaythroughEnough buffered to play throughAutoplay long content confidently

Examples Gallery

Inline oncanplay on audio, addEventListener on video, and media load event order.

👀 Live Preview

Load the audio — when enough data is buffered, status updates:

Waiting for canplay…

Example — Inline oncanplay on audio

Run a function when playback can start:

inline-oncanplay.html
<audio controls oncanplay="handleCanPlay()">

  <source src="song.mp3" type="audio/mpeg">

</audio>



<script>

  function handleCanPlay() {

    console.log("Media can start playing.");

  }

</script>
Try It Yourself

How It Works

The browser fires canplay on the audio element when playback can begin. The inline oncanplay attribute wires up the handler.

Dynamic Values with JavaScript

Attach the handler with addEventListener:

dynamic-oncanplay.html
<script>

  document.getElementById("clip").addEventListener("canplay", function () {

    console.log("Video ready to play.");

  });



  // Or property form:

  document.getElementById("clip").oncanplay = function () { /* … */ };

</script>
Try It Yourself

How It Works

Register the listener once at page load. When the video buffers enough data, canplay runs your readiness code.

Example — Media event order

See where canplay fits in the load sequence:

canplay-timeline.html
audio.addEventListener("loadedmetadata", () => { /* duration known */ });

audio.addEventListener("loadeddata", () => { /* first frame */ });

audio.addEventListener("canplay", () => { /* can start */ });

audio.addEventListener("canplaythrough", () => { /* can play through */ });
Try It Yourself

How It Works

canplay means “ready to start,” not “fully downloaded.” Use canplaythrough when you need confidence for uninterrupted playback.

♿ Accessibility

  • Provide captions and transcripts — Media events do not replace accessible alternatives for audio and video content.
  • Do not autoplay with sound — Respect user preferences; use canplay to enable controls, not surprise playback.
  • Avoid alert() on canplay — Update visible status or hide loaders instead of blocking dialogs.
  • Keyboard controls — Native controls attribute supports keyboard users; custom players need full keyboard support.
  • Loading state — Announce buffer readiness to assistive tech with live regions if you hide native controls.

🧠 How oncanplay Works

1

Media starts loading

Browser fetches the file.

loadstart
2

Data buffers

Metadata and frames arrive.

loadeddata
3

canplay fires

Enough to start playback.

oncanplay
=

Playback can begin

Enable play UI.

Browser Support

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

DOM Events · Fully supported

Universal oncanplay support

All major browsers fire the underlying event and honor the oncanplay 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
oncanplay attribute 99% supported

Bottom line: Universal support on media elements. Test with slow network throttling to see canplay timing.

💡 Best Practices

✅ Do

  • Use addEventListener on the media element — Clearer than inline oncanplay.
  • Hide loaders on canplay — Show spinners during load, remove them when canplay fires.
  • Handle waiting + canplay — Re-show loaders on waiting, hide again on canplay.
  • Provide fallbacks — Include text inside audio/video for unsupported browsers.
  • Use preload wisely — preload="metadata" affects when events fire.

❌ Don’t

  • Do not confuse with canplaythrough — canplay = can start; canplaythrough = likely uninterrupted.

Conclusion

The oncanplay attribute runs JavaScript when enough media data is buffered and the canplay event fires on audio or video. Use it to enable playback UI and hide loading indicators.

Prefer addEventListener("canplay", …), pair with waiting for re-buffering, and use oncanplaythrough when you need confidence for uninterrupted playback.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about oncanplay

Bookmark these before wiring your next event handler.

5
Core concepts
🌐 02

audio / video

Media only.

Scope
🔄 03

Hide loader

On canplay.

Pattern
📝 04

addEventListener

Preferred.

Modern
05

Not fully loaded

Can re-fire.

Note

❓ Frequently Asked Questions

It runs JavaScript when the canplay event fires — when enough media data is buffered that playback can start.
audio and video elements. The event fires on the media element loading the resource.
oncanplay means playback can start. oncanplaythrough means the browser estimates it can play through without stopping to buffer.
No. Only enough data is buffered to begin. The rest may still download during playback.
Prefer media.addEventListener("canplay", …). Inline oncanplay works for simple demos.
Yes. After seeking or re-buffering (waiting), canplay can fire again when enough data is available.

Handle media ready to play

Practice inline oncanplay, addEventListener, and media event order in the Try It editor.

Try oncanplay 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