31

timeupdate-eventなどのオーディオイベントがDOMツリーをバブルアップしないことがわかるまで、私の一部のJavascriptが機能しないのはなぜだろうと思っていました。

オーディオタグとビデオタグのイベントをバブルさせない理由はありますか?

4

1 に答える 1

46

イベントバブリングが存在する理由は、どの要素がイベントの意図されたターゲットであるかというあいまいな問題を解決するためです。それで、divをクリックした場合、divまたはその親をクリックすることを意味しましたか?子にクリックハンドラーがアタッチされていない場合は、親をチェックします。あなたはそれがどのように機能するか知っていると確信しています。

オーディオイベントがバブルしない理由は、他の要素では意味がないためです。オーディオ要素自体またはその親divのどちらを対象としているかにかかわらず、オーディオ要素でをトリガーするときにあいまいさはtimeupdateないため、バブルする必要はありません。

ここでイベントバブリングのより完全な履歴を読むことができます

イベントの委任

イベントのキャプチャフェーズを利用することで、イベントの委任は引き続き可能です。addEventListenerの3番目の引数としてtrueを追加するだけで、次のようになります。

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

このイベントはバブルしませんが、DOMツリーを下って行き、。で停止できないことに注意してstopPropagationください。

これをjQueryの.on/.offメソッドで使用する場合(たとえば、名前空間やその他のjQueryイベント拡張機能を使用する場合)。webshimライブラリから取得した次の関数は、便利になるはずです。

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

使用法:

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

$(document).on('play', function(e){
    $('audio, video').not(e.target).each(function(){
        this.pause();
    });
});
于 2012-09-27T21:36:49.570 に答える