3

Ok lets say I have

<div id="container"/>

and I put a button in this container with id = "button". Then I make .click handler for it

$("#button").click(function() {
foo();
}

Then I change the innerHTML of the div like this:

$("#container").html = "<h1> Foo </h1>";

Then I set timer for let's say 5 seconds that after that will execute the following code :

function(){
$("#container").html = "<button id="button" type="button">Click Meh!</button>"
$("#button").click(function() {
foo();
}
}

My question is: The first button was "destroyed", so was the first .click() handler for it destroyed too? Or the second .click() will just make a second handler for the same button and if I want to have only 1 handler I have to use $("#button").off("click") before calling the second .click() ?

chnging
  • 746
  • 1
  • 8
  • 27
  • possible duplicate of https://stackoverflow.com/questions/595808/is-it-possible-to-append-to-innerhtml-without-destroying-descendants-onclick-fu – Bergi Jun 06 '15 at 15:41

3 Answers3

5
  1. Yes, when you removed the element (by overwriting the html of the element), you've disassosciated the click handler with the element.

  2. Instead, we should just be looking at delegating the event. We target a static parent element (like container), and delegate the event to it:

$('#container').on('click', '#button', foo);

Now when the button is clicked, we'll fire off the foo function. Even if you remove the button and add it later, the event will still be delegated to '#container'.

Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
  • Good answer. I was going to write about this while throwing in a little bit about the DOM tree. – Master Yoda Feb 05 '15 at 16:12
  • And what happens with the memory that was used for the function? I mean does it really remove the function or just leave it like a "zombie" there I mean function that just can't get to ? – chnging Feb 05 '15 at 16:12
  • 2
    @chnging: A small, but important part of this answer is missing: Javascript is garbage collected, so when the event handler gets disassociated, since it was defined as an anonymous function, nothing else has a reference to it anymore, so the function will become available for garbage collection. – doldt Feb 05 '15 at 16:13
1

Yes once you deleted the button the first handler will also destroyed because you are using ".click()" function. You no need to explicitly remove that click handler.

or else use the below ".on" function then you no need to write the function again and again. it will check dynamically adding elements and attach the events.

$( "body" ).on( "click", "#button", function() {
 foo();
});
sai sudhakar
  • 204
  • 1
  • 2
  • 8
1

If your question is if you have to re-bind the onclick handlers when the dom changes, the answer is yes.

If you're asking what happens to the handler function, my guess is it will get garbage collected when the node gets deleted, if you want to avoid the creation of several functions, just write the handler as named function, and use that instead of anonymous one..

If you're asking whether the handler will get bound twice: it will get bound to whatever is in the selection result, if the first button exists when you run the .click then it will, though #id only returns 1 node so, it will bind to the first #button it finds, regardless of if it's already bound...