jquery $('body').on('click') always needs .off('click') to avoid multiple event firing

Kinesias picture Kinesias · Sep 19, 2012 · Viewed 35.4k times · Source

I have a page where I list my crew members (show_crew.php). The page runs on with infinite scrolling plugin, like Google Images does. At first, I show 10 entries. If the user reaches the bottom of show_crew.php, a new 'show_crew.php' is appended to the old one, showing the next 10 entries.

I heave some Jquery functions embedded in show_crew.php, where I bind events via

$('body').on('click', 'myButton[rel=<? echo $user['id'] ?>]', function() {
    console.log('foo');
})​

Now, as show_crew.php is appended multiple times, the event is also bound to the same button multiple times. I can fix this problem via $('body').off('click', 'myButton') EACH TIME.

This looks ugly. Is there a more elegant way?

thanks, matt

Answer

zzzzBov picture zzzzBov · Sep 19, 2012

You only need to bind the delegated events once. Don't rebind every time the content is loaded.

Using the format of $('body').on('click', '...selector...', function () {...}) will delegate the event handler to the <body> element. What this means is that the body will catch all click events and check whether they occurred on an element that matches ...selector.... If it did, it'll trigger the event handler as if it were triggered on the matched element.

Once you've added the delegate listener, there's no need to worry about rebinding, as the children of <body> can change, and the delegate will persist for new elements. This is a very good thing™.