2012-07-02 17 views
24

Me preguntaba por qué algunos de mis javascript no funcionarían hasta que supuse que los eventos de audio no saltaban al árbol DOM, p. el timeupdate -vent.¿Por qué no fluyen los eventos de audio y video?

¿Hay alguna razón para no dejar que los eventos de la etiqueta de audio y video salgan como burbujas?

Respuesta

29

La razón por la que existe el burbujeo de eventos es resolver la pregunta ambigua de qué elemento es el objetivo deseado del evento. Entonces, si haces clic en un div, ¿quisiste hacer clic en el div o en su padre? Si el niño no tiene un controlador de clic conectado, entonces verifica al padre, y así sucesivamente. Estoy seguro de que sabes cómo funciona eso.

La razón por la cual los eventos de audio no se disparan es porque no tienen sentido en ningún otro elemento. No hay ambigüedad cuando activa un timeupdate en un elemento de audio, ya sea para el elemento de audio en sí o su div principal, por lo que no hay necesidad de pasarlo.

se puede leer una historia más completa de la propagación de eventos here

delegación Evento

delegación evento es todavía posible mediante la utilización de la fase de captura del evento. Basta con añadir cierto como el tercer argumento para addEventListener que se parece a esto:

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

Tenga en cuenta, que este evento no burbujea, pero va por el DOM-árbol y no se puede detener con stopPropagation.

En caso de que quiera usar esto con los métodos .on/.off de jQuery (por ejemplo, para tener espacios de nombres y otras extensiones de eventos jQuery). La siguiente función, tomado forma la webshim library, debe convertirse en ú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(); 
    }); 
}); 
+17

A pesar de que no tiene mucho sentido para propagarse por eventos de medios a otro tipo de elementos, sí tiene sentido para registrar un oyente de eventos global en el 'cuerpo', por ejemplo, que capturaría los eventos de cualquier elemento de medios dentro del documento. –

+0

Es una pena, pero comprensible. Por desgracia, hace "trucos" como el sistema de delegación de jQuery inutilizable. Es decir. Adjuntarías un oyente de "juego" a, p. el cuerpo, y la función se ejecutará siempre que '

+0

¿Alguna razón para no aceptar esta respuesta? – saml

Cuestiones relacionadas