The problem is that the timeupdate
event is not a bubble event . This means that you can not treat it through the parent element, as done in:
$(document).on("timeupdate", "#video", function(){
console.log('video playing');
});
This happens because the event is, in this case, associated with document
and not with #video
¹ element. Making direct event delegation with pure JavaScript is possible in the way you did:
document.addEventListener('timeupdate', function(e){
if(e.target.id == "video"){
console.log('video playing');
}
}, true);
The two forms not (possibly not always) are analogous.
That is, the only way (except for the above) is to associate the event directly with the #video
element. You can do this the moment you enter it in the DOM, as explained by Caio, in your response , in the example 2.
Example 3 of the Caio worked as presented because the click
event is a bubble event .
$(() => {
const player = '<video id="video" width="400" controls><source src="https://www.w3schools.com/html/mov_bbb.mp4"type="video/mp4"><source src="https://www.w3schools.com/html/mov_bbb.ogg"type="video/ogg"></video>';
$("button").on("click", event => {
$("#container").html(player);
$("#video").on("timeupdate", event => {
console.log("Video playing...");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="container"></div>
<button>Adicionar</button>
References
JavaScript | Events bubbles
Javascript - Event order
Why do not audio and video events bubble?
Understanding Event Delegation
Notes
(1) : According to the Understanding Event Delegation page on the official jQuery website, when done something like:
$( "#list" ).on( "click", "a", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});
The click
event is delegated to the #list
element and, when treated, it is checked whether the event target matches the selector passed in the second parameter. Reading:
According to the summary on the page:
Event-related to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach to a single event listener for elements that exist now in the future.
The on
function actually makes use of the bubbling effect, or event propagation, for these cases, so for an event that does not propagate, it will not work.
(2) : Apparently the two forms are analogous when the event in question propagates through the DOM, since the event triggered on the target element will also be triggered on its predecessor elements, also in the document
element. Using the third parameter in addEventListener
, capture
, as true causes the event in question to always be triggered also in the element in question, so the event delegation form with pure JavaScript works as expected. In this case, doing something like the example below is also valid:
const container = document.getElementById("container");
container.addEventListener('timeupdate', function(e) {
if(e.target.id == "video"){
console.log('video playing');
}
}, true);
I have not yet found any documentation that tells you if the on
function treats all events as bubble
or whether there is a different behavior for events that are not. In note 1, it is said that the on
event actually uses the bubbling effect of the event to work, but it is not conclusive if it does this regardless of the event.