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

标签 javascript html audio video dom-events

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

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

最佳答案

事件冒泡之所以存在,是为了解决事件的预期目标是哪个元素的歧义问题。那么,如果您单击一个 div,您是要单击该 div 还是它的父级?如果子项没有附加点击处理程序,则它会检查父项,依此类推。我相信您知道它是如何工作的。

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

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

事件委托(delegate)

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

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

请注意,此事件不会冒泡,而是沿着 DOM 树向下移动,并且无法使用 stopPropagation 停止。

如果您想将它与 jQuery 的 .on/.off 方法一起使用(例如,具有命名空间和其他 jQuery 事件扩展)。以下函数取自 webshim library , 应该变得有用:

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

关于javascript - 为什么音视频事件不冒泡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11291651/

相关文章:

javascript - Alfresco - 从服务器端 JavaScript 获取 URL

javascript - 未定义的处理程序?

javascript - 当焦点不在输入中时允许按 ENTER 提交 FORM

android - 通过 WiFi 在 Android 手机之间流式传输语音

javascript - jquery .each 在继续循环之前等待函数完成

javascript - 如何获取字符串的实际长度?

html - 选择选项时设置 $_GET 值

html - Bulma 表单控件宽度在包裹在表单标签中时被抑制

windows - 使用声音加密任何文件?

python - 如何在没有中间音频文件的情况下将 pydub `AudioSegment` 转换为流媒体目的?