从 jquery 中的动态内容捕获所有音频结束事件
Catching all audio end events from dynamic content in jquery
我见过类似的问题 - 但不能解决我的问题!
我的页面上有音频,当一个结束时,我想开始下一个,但我什至无法触发结束...
我把代码缩减为:
function DaisyChainAudio() {
$().on('ended', 'audio','' ,function () {
alert('done');
});
}
这是从我的 page/code 调用的(并执行,设置断点显示)。
据我所知,这应该在文档级别设置处理程序,因此来自任何 'audio' 标记(即使是动态添加)的任何 'ended' 事件都应该被捕获并向我显示警报...
但它永远不会触发。
编辑
从 Çağatay Gürtürk 的建议中借用了一些东西,到目前为止有了这个...
function DaisyChainAudio() {
$(function () {
$('audio').on('ended', function (e) {
$(e.target).load();
var next = $(e.target).nextAll('audio');
if (!next.length) next = $(e.target).parent().nextAll().find('audio');
if (!next.length) next = $(e.target).parent().parent().nextAll().find('audio');
if (next.length) $(next[0]).trigger('play');
});
});
}
我仍然想在文档级别设置它,这样我就不必担心在添加动态元素时添加它...
试试这个:
$('audio').on('ended', function (e) {
alert('done');
var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
});
请注意,当您动态创建新音频时,您应该分配事件。一个快速而肮脏的解决方案是:
function bindEvents(){
$('audio').off('ended').on('ended', function (e) {
alert('done');
var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
});
}
和 运行 bindEvents 每当你 create/delete 一个音频元素时。
它不触发的原因是,媒体事件(那些特别属于 audio 或 video 的媒体事件,例如 play
, pause
、timeupdate
等)不要起泡。您可以在 this question 的答案中找到对此的解释。
所以使用他们的解决方案,我捕获了 ended
事件,这将允许为动态添加的音频元素设置触发器。
$.createEventCapturing(['ended']); // add all the triggers for which you like to catch.
$('body').on('ended', 'audio', onEnded); // now this would work.
JSFiddle demo
事件捕获代码(取自另一个SO答案):
$.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);
}
});
});
};
})();
我见过类似的问题 - 但不能解决我的问题!
我的页面上有音频,当一个结束时,我想开始下一个,但我什至无法触发结束...
我把代码缩减为:
function DaisyChainAudio() {
$().on('ended', 'audio','' ,function () {
alert('done');
});
}
这是从我的 page/code 调用的(并执行,设置断点显示)。
据我所知,这应该在文档级别设置处理程序,因此来自任何 'audio' 标记(即使是动态添加)的任何 'ended' 事件都应该被捕获并向我显示警报...
但它永远不会触发。
编辑
从 Çağatay Gürtürk 的建议中借用了一些东西,到目前为止有了这个...
function DaisyChainAudio() {
$(function () {
$('audio').on('ended', function (e) {
$(e.target).load();
var next = $(e.target).nextAll('audio');
if (!next.length) next = $(e.target).parent().nextAll().find('audio');
if (!next.length) next = $(e.target).parent().parent().nextAll().find('audio');
if (next.length) $(next[0]).trigger('play');
});
});
}
我仍然想在文档级别设置它,这样我就不必担心在添加动态元素时添加它...
试试这个:
$('audio').on('ended', function (e) {
alert('done');
var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
});
请注意,当您动态创建新音频时,您应该分配事件。一个快速而肮脏的解决方案是:
function bindEvents(){
$('audio').off('ended').on('ended', function (e) {
alert('done');
var endedTag=e.target; //this gives the ended audio, so you can find the next one and play it.
});
}
和 运行 bindEvents 每当你 create/delete 一个音频元素时。
它不触发的原因是,媒体事件(那些特别属于 audio 或 video 的媒体事件,例如 play
, pause
、timeupdate
等)不要起泡。您可以在 this question 的答案中找到对此的解释。
所以使用他们的解决方案,我捕获了 ended
事件,这将允许为动态添加的音频元素设置触发器。
$.createEventCapturing(['ended']); // add all the triggers for which you like to catch.
$('body').on('ended', 'audio', onEnded); // now this would work.
JSFiddle demo
事件捕获代码(取自另一个SO答案):
$.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);
}
});
});
};
})();