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
steve 2011-09-24 21:12:52 -0400
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 2011-10-21 16:16:27 -0400
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 ;). Cheersraystrach 2011-10-28 18:48:34 -0400
i call it genius!! thanks aimup and sholsinger.
Dave 2011-11-03 18:16:12 -0400
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! DaveStephen 2011-11-03 18:48:03 -0400
@Dave I believe that may be exactly what happened in my case. Thanks for your contribution.
Stephen 2012-03-14 09:13:53 -0400
@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 2012-03-20 13:51:29 -0400
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 2012-03-21 12:33:57 -0400
@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 2012-05-22 13:05:20 -0400
Thanks, needed to stay with a old 1.6.2 version of jQuery and this worked perfectly.
Techie Talks 2012-05-28 05:48:47 -0400
Kewl! I think it's similar to addtng return false drirect after an event?
$('#btn').live('click',function(){ $.ajax({ ... }); return false; });
dev 2012-07-25 17:49:58 -0400
I love you! thanks.
Ved Sahani 2012-08-24 08:31:33 -0400
Amazing, thanks for solution
Tim 2012-09-13 11:26:39 -0400
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 2012-10-16 10:50:30 -0400
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 2012-10-27 13:50:21 -0400
[...] 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 2012-10-28 21:43:32 -0400
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 2012-11-09 02:11:34 -0500
Thnxx it worked like a charm..........
Mark 2012-11-14 16:27:21 -0500
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 2012-11-15 15:00:38 -0500
Brilliant! Worked perfectly for me!
asma gheisari 2012-11-26 08:45:04 -0500
thanks a milion
tien thanh 2012-12-14 12:10:19 -0500
Thank you so much. It's working to me.
Mohammed 2012-12-18 15:33:41 -0500
Thanks man. I spent two days of my life trying to solve a similar problem. Thank you so much for sharing this.
Erick 2012-12-20 13:33:46 -0500
Thank you very much! You should solved a major issue for me!
Jime 2013-01-13 16:32:40 -0500
thank you so much! you made my day! :] :D
Gopesh 2013-01-31 05:02:44 -0500
Thanks a Lot man!!!..Good snippet
Vineet 2013-02-01 06:53:49 -0500
it works for mw as well...You rocks.
sumit sharma 2013-02-11 08:21:52 -0500
Thanks buddy thanks a lot yes you are life savior you salved my huge problem its appreciative.
Eugene 2013-02-20 06:02:01 -0500
Simple and great! Thanks a lot, Sholsinger. Also instead of "live" can be used "on" maybe
Rajarajan G 2013-02-27 04:30:57 -0500
Thanks a lottttt !!! Its working very Fine Dude!!! Good Idea in Jquery !!!!!!!!!!!!:)
Angelo 2013-08-14 15:54:55 -0400
Great job guy! You saved my a$$!
crazyku 2013-08-18 22:49:13 -0400
Thank you very much. Your information is safe me.
Matt Langston 2013-08-21 09:01:35 -0400
You could also use jquery's stopImmediatePropagation() also right?
Stephen 2013-08-21 13:40:51 -0400
Yes that does work as well and is less verbose: http://jsfiddle.net/sholsinger/pY87e/
Magnus 2013-08-22 02:44:03 -0400
Yes! Solved my problem too! Unbind before binding didn't work, but this did. Awesome!
Prevent jQuery multiple event triggering | Gajotres.net 2013-09-26 17:03:46 -0400
[…] Note Solution found here: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/ […]
Belinda 2013-10-31 12:37:49 -0400
your such a charm...I have been trying to solve this issue and found your site..Thanks so much for sharing!
Belinda 2013-10-31 12:48:31 -0400
nice solution very good
Prevent Multiple Event Firing | .blog 2013-11-12 21:01:30 -0500
[…] 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 2013-11-22 07:25:05 -0500
thanks man!!!