我想知道为什么我的某些javascript无法工作,直到我认为音频事件没有冒出DOM树,例如timeupdate
- 事件。
是否有理由不让音频和视频标签的事件冒泡?
答案 0 :(得分:33)
事件冒泡存在的原因是解决了哪个元素是事件的预期目标的模糊问题。所以,如果你点击一个div,你的意思是单击div还是它的父级?如果孩子没有附加点击处理程序,那么它会检查父项,依此类推。我相信你知道它是如何运作的。
音频事件不起泡的原因是因为它们对任何其他元素都没有意义。当您在音频元素上触发timeupdate
时,无论它是否适用于音频元素本身或其父div,都没有歧义,因此无需冒泡它。< / p>
您可以阅读更全面的事件冒泡历史记录here
活动委派
通过利用事件的捕获阶段仍然可以进行事件委派。只需添加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();
});
});