2

What happens when I bind an event handler to a DOM element and then subsequently destroy the DOM element? Do I have to go through a process of unbinding the event handlers?

<div id="el1">
    <span id="c">Click Me!</span>
</div>
<span id="note">Note...</span>
<script>
    var i=0;
    $("#c").click(function(){
        i++;
        $("#note").html("'Click Me!' was clicked.");
        $("#el1").html("<span id=\"c\">Click Me! ("+i+" time)</span>");
    });
</script>

In Action: http://jsfiddle.net/lordloh/FyLdM/

Obviously, the even handler does not bind to the new DOM object with same id. The work around I am using is

<div id="el1">
   <span id="c">Click Me!</span>
</div>
<span id="note">Note...</span>
<script>
var i=0;
$("#c").click(clickHandler);

function clickHandler(){
    i++;
    $("#note").html("'Click Me!' was clicked.");
    $("#el1").html("<span id=\"c\">Click Me! ("+i+" time)</span>");
    $("#c").click(clickHandler);
}
</script>

In Action: http://jsfiddle.net/lordloh/FyLdM/1/

What I am concerned about is whether this is a bad practice or is such a thing acceptable? What happens if this sequence is repeated millions of times? Could the javascript engine run the risk of running out of memory?

Lord Loh.
  • 2,237
  • 4
  • 35
  • 62
  • Your example doesn't really make sense... Why would you not just call the `.html()` method on the `#c` directly, rather than recreating the element? – ahren Jan 30 '13 at 22:42
  • It is still unique :-) Two DOM objects with the same ID never co-existed. – Lord Loh. Jan 30 '13 at 22:42
  • @ahren - It's just an example. The actual code is much complicated where it was simpler do something as in this example. In my actual code, the number of `` in the `
    ` changed (added and removed) with time. and each span had event handlers bound to it.
    – Lord Loh. Jan 30 '13 at 22:44
  • Another thing you need to ask yourself if it's likely that this will occur millions of times. You shouldn't focus on performance until it becomes an issue, and then you optimize. Or if you're really worried about it, do it at the end. – ahren Jan 30 '13 at 23:34
  • The app may end up being deployed on a kiosk running 24x7 for days. A hack could be a refresh of the page every few hours. :-) – Lord Loh. Jan 31 '13 at 00:22

2 Answers2

2

You should focus on event delegation instead.

$('#someWrapper').on('click', '.someClass', function() {
   // do your stuff.
});

Then you can add elements to the wrapper, assign them .someClass and the event will fire.

AlienWebguy
  • 73,720
  • 16
  • 109
  • 137
  • And here is why: http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation/1688293#1688293 – Diodeus - James MacFarlane Jan 30 '13 at 22:31
  • Thank you. While this is a nice way and something I might eventually end up doing, I still want to know what happened to the event binding and how is it internally handled? Is this something for the garbage collector?? – Lord Loh. Jan 30 '13 at 22:35
  • It depends on the browser. Webkit and Mozilla have great GC and will unbind events and handle closures properly when nodes are removed from the DOM. IE on the other hand, fails miserably in this area - especially IE7. – AlienWebguy Jan 30 '13 at 22:42
0

Instead of having to rebind the event each time the element is created, you should use event delegation instead as AlienWebguy suggests. However, in this case there is nothing pointing to the jQuery objects after they are removed from the dom, so garbage collection should take care of cleaning up unused variables.

Justin Bicknell
  • 4,716
  • 16
  • 25
  • Garbage collection was what I was thinking of. Are you sure of this? Or is the garbage collection just an educated guess? – Lord Loh. Jan 30 '13 at 22:36