Por que os events de áudio e vídeo não borbulham?

Eu estava me perguntando por que algum javascript meu não iria funcionar até eu percebi que os events de áudio não borbulharam na tree DOM, por exemplo, o timeupdate -event.

Existe uma razão para não deixar os events da bolha de tags de áudio e vídeo?

A razão pela qual existe o borbulhamento de um evento é resolver a questão ambígua de qual elemento é o alvo pretendido do evento. Então, se você clicar em um div, você quis clicar no div ou no pai dele? Se o filho não tiver um manipulador de clique anexado, ele verificará o pai e assim por diante. Tenho certeza que você sabe como isso funciona.

A razão pela qual os events de áudio não borbulham é porque eles não fazem sentido em nenhum outro elemento. Não há ambigüidade quando você triggers uma timeupdate em um elemento de áudio, seja para o elemento de áudio em si ou para o div pai, portanto não há necessidade de borbulhar.

Você pode ler uma história mais completa do evento borbulhando aqui

Delegação de events

A delegação de events ainda é possível utilizando a fase de captura do evento. Simplesmente adicione true como o terceiro argumento para addEventListener que se parece com isto:

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

Observe que esse evento não borbulha, mas desce na tree DOM e não pode ser interrompido com stopPropagation .

Caso você queira usar isso com os methods .on / .off do jQuery (por exemplo, para ter namespacing e outras extensões de evento jQuery). A seguinte function, tomada da biblioteca webshim , deve se tornar útil:

 $.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); } }); }); }; })(); 

Uso:

 $.createEventCapturing(['play', 'pause']); $(document).on('play', function(e){ $('audio, video').not(e.target).each(function(){ this.pause(); }); });