Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't audio and video events bubble?

I was wondering why some Javascript of mine would not work until I figured that the audio events did not bubble up the DOM tree, e.g. the timeupdate-event.

Is there a rationale for not letting the events of the audio- and video-tag bubble?

like image 674
k0pernikus Avatar asked Jul 02 '12 10:07

k0pernikus


People also ask

Do events bubble up or down?

A bubbling event goes from the target element straight up. Normally it goes upwards till <html> , and then to document object, and some events even reach window , calling all handlers on the path.

Why do we need event bubbling?

Event bubbling is a method of event propagation in the HTML DOM API when an event is in an element inside another element, and both elements have registered a handle to that event. It is a process that starts with the element that triggered the event and then bubbles up to the containing elements in the hierarchy.

Do events bubble by default?

In modern browsers, by default, all event handlers are registered for the bubbling phase. So in our current example, when you click the video, the event bubbles from the <video> element outwards to the <html> element.


1 Answers

The reason why event bubbling exists is solve the ambiguous question of which element is the intended target of the event. So, if you click on a div, did you mean to click the div, or its parent? If the child doesn't have a click handler attached, then it checks the parent, and so on. I'm sure you know how that works.

The reason why audio events don't bubble is because they don't make sense on any other element. There's no ambiguity when you trigger a timeupdate on an audio element whether it's meant for the audio element itself or its parent div, so there's no need to bubble it.

You can read a fuller history of event bubbling here

Event delegation

Event delegation is still possible by utilizing the capturing phase of the event. Simply add true as the third argument for addEventListener which looks like this:

document.addEventListener('play', function(e){     //e.target: audio/video element }, true); 

Note, that this event doesn't bubble, but goes down the DOM-tree and can't be stopped with stopPropagation.

In case you want to use this with the jQuery's .on/.off methods (for example to have namespacing and other jQuery event extensions). The following function, taken form the webshim library, should become usefull:

$.createEventCapturing = (function () {     var special = $.event.special;     return function (names) {         if (!document.addEventListener) {             return;         }         if (typeof names == 'string') {             names = [names];         }         $.each(names, function (i, name) {             var handler = function (e) {                 e = $.event.fix(e);                  return $.event.dispatch.call(this, e);             };             special[name] = special[name] || {};             if (special[name].setup || special[name].teardown) {                 return;             }             $.extend(special[name], {                 setup: function () {                     this.addEventListener(name, handler, true);                 },                 teardown: function () {                     this.removeEventListener(name, handler, true);                 }             });         });     }; })(); 

Usage:

$.createEventCapturing(['play', 'pause']);  $(document).on('play', function(e){     $('audio, video').not(e.target).each(function(){         this.pause();     }); }); 
like image 99
saml Avatar answered Oct 08 '22 15:10

saml