Prevent jQuery.live() Handlers From Firing Multiple Times
Recently I was working on something where I needed to use jQuery's .live() event handling. The problem I was experiencing was that my .live() handler was firing multiple times for the same event. I devised a rather simple way to avoid this issue and I'm going to share it with all of you.
The first thing we need to know is that the event object which is passed to all of the event handlers for that given event is the same object. You can modify it and the next handler will get the same object you just modified. So my method takes advantage of that fact and adds a .handled property to the jQuery event object. My event handler method then checks to see if this property is equal to true and if it isn't, then it executes it's payload. Otherwise it just returns false to prevent bubbling.
function myLiveEventHandler(event)
{
if(event.handled !== true)
{
// put your payload here.
// this next line *must* be within this if statement
event.handled = true;
}
return false;
}
$('selector').live('event', myLiveEventHandler);
There you have it. We have bound a .live() event handler and prevented it from running twice. (If it just so happened that it were bound more than once.) Why might it be bound more than once? If you use jQuery Mobile or some sort of AJAX loading method for content then you may duplicate your event handler binding every time you load a new page. This is probably the poor man's way of handling this problem and you should probably try to find a way to avoid double binding the event instead. Who has the time for that?
Comments (39)
comments powered by Disqussteve
Curious,
Don't you at some point want to set event.handled = false; as the initializer.. What if the handled property/var starts out as true when initialized?
AimUp
Nice post Sholsinger.
I was looking for this solution for a while.
I also found that if you .die() before you .live (or .undelegate() before you .delegate ), the multiple bindings are avoided all together.
for example:
So to answer your question - I guess I have time for that ;).
Cheers
raystrach
i call it genius!!
thanks aimup and sholsinger.
Dave
Another solution to the root problem is to make sure you don't have any old AJAX-loaded pages lying around in your DOM by adding this JS code:
This fixed a problem for me where jquery mobile was loading the same page twice in the DOM (even though I had the data-url set) because the first time I loaded the page I didn't have any query params and the second time I did. So jQM treated the second load as a new page, but of course it had all the same DOM elements which meant tons of duplicate IDs in the DOM.
Hope this helps!
Dave
Stephen
@Dave I believe that may be exactly what happened in my case. Thanks for your contribution.
Stephen
@steve
The handled property will never start out as "true" when initialized unless you initialize it as such. It will be "undefined" until set. When set and uninitialized it will be "null". It will not hold true or false until you set it as such.
I should also mention it might be a good idea to give each event handler a unique handled property on the event so that you can have multiple event handlers handle the same event if necessary.
Luka
If it's of any help to anyone... Use .on() instead of .live() and you shouldn't experience problems of methods beeing called more then once...
Stephen
@luka that would work, if you're able to use jQuery 1.7. http://api.jquery.com/on/
However this article was written months before the release of 1.7 and is still relevant to those who--for whatever reason--cannot use 1.7.x.
Christopher
Thanks, needed to stay with a old 1.6.2 version of jQuery and this worked perfectly.
Techie Talks
Kewl! I think it's similar to addtng return false drirect after an event?
$('#btn').live('click',function(){ $.ajax({ ... }); return false; });
dev
I love you! thanks.
Ved Sahani
Amazing, thanks for solution
Tim
Thanks! Don't know why I was having the multiple binding problem, but your fix ended it, and as you said, who has time to figure out why it was happening once it isn't anymore?
john
Thanks for this solution.
That solved the problem but then my click event does not work.
I dont get it because mouseover, mouseout works fine.
Can anyone please help me out with it?
Dynamic tooltip using JQuery Ajax and JQuery Tools « mjtoolbox
[...] Prevent multiple Ajax requests : After implement all above, I found that somehow Ajax request fires multiple times. Some people suggested that I use .dead() before .live(), but I did a simple approach. I used event.handled check before Ajax request. Also, check the default content if it is already updated. Good resource here. [...]
Jeff Parr
If I have offending click event inside of live() - especially in dynamic listing where many live() can be fired, e.g. one for each list element user works with simultaneously, I usually unbind right before, to save trouble -
e.g.:
$('.click_button').unbind("click");
$('.click_button').live("click",function(){
//code
}
Same I do for any nested clicks inside of live().
Usually it gets job done.
Rupesh
Thnxx it worked like a charm..........
Mark
Saved my life! Thank you! Slight change up because my if/then/else logic was already complicated enough without another level:
$('.hotspot').live("mouseup", function(e) {
e.preventDefault();
if(e.handled === true) return false;
e.handled = true;
//my code here
return false;
});
andre
Brilliant! Worked perfectly for me!
asma gheisari
thanks a milion
tien thanh
Thank you so much. It's working to me.
Mohammed
Thanks man. I spent two days of my life trying to solve a similar problem. Thank you so much for sharing this.
Erick
Thank you very much! You should solved a major issue for me!
Jime
thank you so much! you made my day! :] :D
Gopesh
Thanks a Lot man!!!..Good snippet
Vineet
it works for mw as well...You rocks.
sumit sharma
Thanks buddy thanks a lot yes you are life savior you salved my huge problem its appreciative.
Eugene
Simple and great! Thanks a lot, Sholsinger.
Also instead of "live" can be used "on" maybe
Rajarajan G
Thanks a lottttt !!!
Its working very Fine Dude!!!
Good Idea in Jquery !!!!!!!!!!!!:)
Angelo
Great job guy! You saved my a$$!
crazyku
Thank you very much. Your information is safe me.
Matt Langston
You could also use jquery's stopImmediatePropagation() also right?
Stephen
Yes that does work as well and is less verbose: http://jsfiddle.net/sholsinger/pY87e/
Magnus
Yes! Solved my problem too! Unbind before binding didn't work, but this did. Awesome!
Prevent jQuery multiple event triggering | Gajotres.net
[…] Note Solution found here: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/ […]
Belinda
your such a charm...I have been trying to solve this issue and found your site..Thanks so much for sharing!
Belinda
nice solution very good
Prevent Multiple Event Firing | .blog
[…] fire x number of times. That is not what we want. I have search the web for help, and encounter a post to solve this […]
chandu
thanks man!!!