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)
  
});