3

I've got a bunch divs which each contain a remove link attached with the click event below:

  var observeRemoveRoom = function
    $('.remove_room').click(function(){     
      $(this).parent().removeClass('active');
    });
  }

Clicking it removes the 'active' class of the parent (the div). I call this observeRemoveRoom function on window load which works fine.

The thing is, I have another function which adds more of the same divs. Since the a.remove_room links contained within the new divs weren't around on window.load I need to call observeRemoveRoom.

Am I somehow duplicating the event handlers? Does jQuery overwrite them? If so should I unbind the handlers?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
digitalWestie
  • 2,647
  • 6
  • 28
  • 45

3 Answers3

3

Each time you call observeRemoveRoom jQuery will add a new unique event handler function for a click event.

So yes, you need to .unbind() either all currently bound handlers by just calling .unbind() without arguments, or be specific and pass in a function reference.

jAndy
  • 231,737
  • 57
  • 305
  • 359
1

Yes, you will be duplicating the event-handlers if you call observeRemoveRoom again, but it might not be noticeable since you are only calling the removeClass method which does nothing if the class is not found, which would be the case after the first listener is triggered.

Instead you can un-bind and re-bind the click event each time, like:

 var observeRemoveRoom = function(){
    var remove_class = function(){     
      $(this).parent().removeClass('active');
    };
    $('.remove_room').off('click', remove_class).on('click', remove_class);
  }

But that said, it is recommended that you do this outside this function`, rather than binding and unbinding the event every time, like:

$(document).ready(function(){
    var remove_class = function(){     
      $(this).parent().removeClass('active');
    };
    // If the element exists at dom ready, you can bind the event directly
    $('.remove_room').on("click", remove_class);
    // If the element is added in dynamically, you can [delegate][1] the event
    $('body').on("click", '.remove_room', remove_class);
    // Note: Although I've delegated the event to the body tag in this case
    // I recommend that you use the closest available parent instead
});

http://api.jquery.com/on/#direct-and-delegated-events : [1]

S P
  • 1,801
  • 6
  • 32
  • 55
1

You can try a live query to keep them updated: http://docs.jquery.com/Plugins/livequery

mamapitufo
  • 4,680
  • 2
  • 25
  • 19
  • 1
    Huh, what's that plugin? Just use on() with a selector. – Bergi Jul 11 '12 at 10:55
  • on() will only attach the events to the results of the query at the time you called it. Live queries add/remove the events when the DOM changes. – mamapitufo Jul 11 '12 at 11:03
  • 2
    No, not when the DOM changes but when a jQuery method is called. Urghh. Better use [delegated events](http://api.jquery.com/on/#direct-and-delegated-events). – Bergi Jul 11 '12 at 11:14