Javascript 为什么不';音频和视频事件泡沫?

Javascript 为什么不';音频和视频事件泡沫?,javascript,html,audio,video,dom-events,Javascript,Html,Audio,Video,Dom Events,我想知道为什么我的一些Javascript无法工作,直到我发现音频事件没有在DOM树上冒泡,例如timeupdate-事件 是否有理由不让音频和视频标签的事件冒泡?事件冒泡存在的原因是为了解决以下不明确的问题:哪个元素是事件的预期目标。那么,如果你点击一个div,你是想点击这个div还是它的父节点?如果子级没有附加click处理程序,则会检查父级,依此类推。我相信你知道这是怎么回事 音频事件不冒泡的原因是它们在任何其他元素上都没有意义。当您在音频元素上触发timeupdate时,无论它是针对音频

我想知道为什么我的一些Javascript无法工作,直到我发现音频事件没有在DOM树上冒泡,例如
timeupdate
-事件


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

事件冒泡存在的原因是为了解决以下不明确的问题:哪个元素是事件的预期目标。那么,如果你点击一个div,你是想点击这个div还是它的父节点?如果子级没有附加click处理程序,则会检查父级,依此类推。我相信你知道这是怎么回事

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

您可以阅读事件冒泡的更完整历史记录

活动委派

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

document.addEventListener('play', function(e){
    //e.target: audio/video element
}, true);
请注意,此事件不会冒泡,但会沿着DOM树向下移动,不能使用
stopPropagation
停止

如果您希望将其用于jQuery的.on/.off方法(例如,使用名称空间和其他jQuery事件扩展)。以下功能(形式为)应变得有用:

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

虽然将媒体事件冒泡到其他类型的元素没有多大意义,但在
正文
上注册一个全局事件侦听器是有意义的,例如,它可以捕获文档中任何媒体元素的事件。这很遗憾,但可以理解。不幸的是,它确实使jQuery的委托系统等“技巧”无法使用。也就是说,您可以将一个
播放
侦听器附加到例如主体上,并且每当任何
触发该事件时,都会执行该函数。(这实际上是@Sergiu的想法。)这不是我的问题:)我通常不会很快给出赏金,但别担心。