jQuery media event delegation problem
by jmpp77
HTML
<div id="root">Loading ...</div>
CSS
#root {
margin: 1rem;
padding: 1rem;
background-color: yellow;
border-radius: 1rem;
}
audio {
display: block;
margin: 1rem auto;
width: 100%;
}
JavaScript
$(function() {
// ==================================================
// This below is just for demonstrating the problem :
// ==================================================
// Faking API data
let dataThatNormallyComesFromAnAPI = [
{file:'https://cdns-preview-2.dzcdn.net/stream/c-2a004040b90fc27c6c462263d88da592-9.mp3'},
{file:'https://cdns-preview-f.dzcdn.net/stream/c-f17b96a445ebc8c1a28882cbaa9dc83a-7.mp3'},
{file:'https://cdns-preview-b.dzcdn.net/stream/c-b639984a2637d754a40be46c7d110219-5.mp3'}
];
// When window is loaded...
$(window).on('load', function() {
$('#root').empty();
dataThatNormallyComesFromAnAPI
.map(({file}) => `<audio src="${file}" controls></audio>`)
.map(htmlString => $(htmlString))
.forEach($jqElement => $jqElement.appendTo('#root'));
});
/* ============================================
This won't work, because the "play" event
doesn't bubbles upto the document
⬇
=============================================== */
// ❌ doesn't works
$(document).on('play', 'audio', function() {
console.log('An audio tag started to play...');
});
/* ==============
But this will :
⬇
============== */
// ✅ works because the listener is registered during the "capture" phase (3rd argument to "true")
document.addEventListener('play', function() {
console.log('An audio tag started to play...');
}, true); // <-- true : on capture (not bubbling)
});