Capturing all audio content events from dynamic content in jquery
I've seen similar questions but didn't fix my problem!
I have an audio on my page and when it ends I want the next one to start, but I can't even finish starting ...
I cut the code down to this:
function DaisyChainAudio() {
$().on('ended', 'audio','' ,function () {
alert('done');
});
}
This is called from my page / code (and executed, setting a breakpoint shows it).
As I understand it, this should set a document-level handler, so any "completed" events from any "audio" tag (even if added dynamically) should be captured and show me that the warning ...
But it never works.
change
With some borrowings from Chagatay Gyurturk's proposal, there is still this ...
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');
});
});
}
I would like to set this at the document level anyway, so I don't have to worry about adding it when adding dynamic elements ...
source to share
Try the following:
$('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.
});
Note that when dynamically creating a new sound, you must assign events. A quick and dirty solution:
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.
});
}
and fire bindEvents whenever you create / remove an audio element.
source to share
The reason why it does not work, means that media events (those that relate to the audio or video, for example play
, pause
, timeupdate
etc.), do not become bubbles. you can find an explanation for this in the answer to this question .
So using my solution, I captured the event ended
and this would allow triggers for the dynamically added audio elements to be set.
$.createEventCapturing(['ended']); // add all the triggers for which you like to catch.
$('body').on('ended', 'audio', onEnded); // now this would work.
JSFiddle demo
code to capture the event (taken from another SO answer):
$.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);
}
});
});
};
})();
source to share