0

I'm new to jQuery and wrote the following code. Strangely, the jQuery code somehow works even after the time delay. alert() gets called onclick after the time delay. The same thing in javascirpt with .addEventListener() would give error since the element doesn't exist. Can someone explain me how and why jQuery does this?

<div id="outerId" class="outerHolder">
  <div class="innerHolder"></div>
</div>

JS Code:

$("#outerId").on("click touchstart", "#newTag", function (e) {
    alert("OK");
});

setTimeout(function() {
    var tag = '<div id="newTag">Hello World</div>';                  
    $("#outerId").append(tag);
}, 5000);

Here is a jsFiddle of the same: https://jsfiddle.net/jb6pmovb/

kumardeepakr3
  • 395
  • 6
  • 16
  • 1
    What do mean *The same thing in javascirpt would give error*? Care to show what this *same thing* is? – Andrew Li Nov 15 '16 at 05:16
  • you've shown the jQuery code that works, and asked why the non jQuery code doesn't ... do you see a problem with that? Oh, and what you've posted wouldn't do a thing as there are no script tags in the code posted in the question – Jaromanda X Nov 15 '16 at 05:16
  • 1
    Your question makes no sense. Specifically "The same thing in javascript would give error." doesn't make sense, since jQuery is a JavaScript library. – Paul Nov 15 '16 at 05:16
  • Do you mean to ask how jQuery manages to attach event handlers for events on elements that don't exist yet? – Amadan Nov 15 '16 at 05:17
  • 3
    That being said, I believe your confusion is caused by event delegation. If you bind an event handler to an element and then replace that element in the DOM it would not takeover event handlers bound to the old element. In the jQuery above though, nothing is bound to the element with id `#newTag`, instead an onclick handler is bound to `#outerId`, and `event.target` is used to determine which element within `#outerId` was actually clicked. It doesn't matter that the element with `#newTag` doesn't exist when the handler is bound, because the handler is bound to an ancestor of it. – Paul Nov 15 '16 at 05:18
  • I meant, if I use pure javascript based event handler using .addEventListener(). It would fail since there is no `#outerId` available by the time of execution. – kumardeepakr3 Nov 15 '16 at 05:21
  • clearly the problem is that you aren't doing the same thing in "pure" javascript as what you are doing in jQuery – Jaromanda X Nov 15 '16 at 05:23
  • `there is no #outerId available by the time of execution` - why not? if the javascript code is AFTER that div, like it is with the jQuery code, then outerId does exist at the time of execution - if you showed what you believe to be the pure javascript equivalent, I'm sure someone could correct you – Jaromanda X Nov 15 '16 at 05:25
  • Thanks JaromandaX, Paulpro Understood exactly where I was going wrong. – kumardeepakr3 Nov 15 '16 at 05:33

2 Answers2

1

If you are wondering how the click works on an element which is not there at the time of page load, then that's because you are attaching the listener on the outerDiv and using .on

Check out this for the difference between using .on and .click

Community
  • 1
  • 1
Prasanna
  • 10,956
  • 2
  • 28
  • 40
1

My guess is that your query is about the way on() is binding to to the object. When on() is first ran, #newTag does not exist, so you might be wondering why it still triggers when appended after a delay.

This is because #outerId is the object being bound to, which does exist the time on() is called. When you append #newTag, it doesn't alter the outer binding, it simply looks over the children when it is clicked.

With regular js I assume you are using addEventListener, which requires you bind the event to the specific object. If you do try and use that directly on #newTag before it exists, it obviously won't work.


You can see by the docs for on():

selector

Type: String A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.

Community
  • 1
  • 1
Matt Way
  • 32,319
  • 10
  • 79
  • 85