小编典典

为什么音频和视频事件不冒泡?

html

我想知道为什么我的一些JavaScript不能正常工作,直到我发现音频事件没有使DOM树冒泡,例如timeupdate-event。

是否有理由不让音频和视频标签的事件泡沫化?


阅读 459

收藏
2020-05-10

共1个答案

小编典典

存在事件冒泡的原因是解决了哪个元素是事件的预期目标的模棱两可的问题。因此,如果单击div,是不是要单击div或其父级?如果子级没有附加的单击处理程序,则它将检查父级,依此类推。我确定您知道它是如何工作的。

音频事件不会起泡的原因是,它们在任何其他元素上都没有意义。timeupdate无论您是在音频元素本身还是其父div上触发音频元素上的,都不会产生歧义,因此无需冒泡。

活动委托

通过利用事件的捕获阶段,事件委托仍然是可能的。只需将true作为addEventListener的第三个参数添加,如下所示:

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();
    });
});
2020-05-10