2012-07-02 11 views
24

Mi stavo chiedendo perché alcuni miei javascript non funzionassero finché non ho capito che gli eventi audio non erano in bolla sull'albero DOM, ad es. il timeupdate -event.Perché non si verificano eventi audio e video?

C'è un motivo per non lasciare che gli eventi della bolla dei tag audio e video?

risposta

29

Il motivo per cui esiste un bubbling di eventi è risolvere l'ambigua questione di quale elemento è il target previsto dell'evento. Quindi, se fai clic su un div, intendi fare clic sul div o sul suo genitore? Se il bambino non ha un gestore di clic collegato, controlla il genitore e così via. Sono sicuro che sai come funziona.

Il motivo per cui gli eventi audio non sono chiari è perché non hanno senso su nessun altro elemento. Non c'è alcuna ambiguità quando si attiva un timeupdate su un elemento audio indipendentemente dal fatto che sia destinato all'elemento audio stesso o al suo elemento principale div, quindi non c'è bisogno di contenerlo.

si può leggere una storia più completa di bubbling degli eventi here

delegazione evento

delegazione evento è ancora possibile, utilizzando la fase di cattura della manifestazione. Basta aggiungere vero come il terzo argomento per addEventListener che assomiglia a questo:

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

Nota, che questo evento non fa bolla, ma scende il DOM-albero e non può essere fermato con stopPropagation.

Nel caso in cui si desidera utilizzare questo con i metodi .on/.off di jQuery (ad esempio per avere il namespacing e altre estensioni evento jQuery). La funzione seguente, preso forma il webshim library, dovrebbe diventare utile:

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

utilizzati:

$.createEventCapturing(['play', 'pause']); 

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

Mentre non ha molto senso bolla eventi mediatici altro tipo di elementi, non rendere senso per registrare un listener di eventi globale sul 'body', ad esempio, che catturerebbe gli eventi da qualsiasi elemento multimediale all'interno del documento. –

+0

È un peccato, ma comprensibile. Sfortunatamente, le "prese" come il sistema di delega di jQuery sono inutilizzabili. Cioè dovresti collegare un ascoltatore di 'play' ad es. il corpo, e la funzione verrebbe eseguita ogni volta che '

+0

Qualche motivo per non accettare questa risposta? – saml

Problemi correlati