The canplay/canplaythrough events for an HTML5 video are not called on Firefox. Why?

The problem is that your video element has triggered the canplaythrough event before you registered the event handler.

As you pointed out in your own answer, you can put your scripts in the <head>, but this is bad for your page performance.

A better way to fix your problem is to check the readystate attribute and execute your function manually in that case:

var $video = $('video'),
    videoElement = $video[0];

$video.on('canplaythrough', callback);

// If the video is in the cache of the browser,
// the 'canplaythrough' event might have been triggered
// before we registered the event handler.
if (videoElement.readyState > 3) {
  callback();
}

The most likely reason you're seeing this probably has to do with timing issues. You stated in your accepted answer that putting jQuery into the head rather than the footer solves the problem. This tells me that the issue is DOM parsing and script execution order. The most likely culprit is that the "canplay" and "canplaythrough" events were being fired before jquery and your page script were parsed and the event handlers added - but only sometimes, depending on network traffic and load times. By putting the script in the head, you forced your event binding to occur before the DOM elements were created, thereby ensuring that you didn't miss any events.

As an aside, the performance benefits of putting script elements at the bottom of the page are debatable. If you really want to tweak page performance, use something like LABjs to manage parallel script loading.


In my case, this was determined by the preload attribute specified for the element. I did not have it specified at all, so different browsers were choosing to do different things.

Once I specified preload="auto", the on("canplay") event handler worked fine/as expected.