Home Blog Prevent jQuery events from firing multiple times

Prevent jQuery events from firing multiple times

     
    14
    This is one of the most interesting jQuery errors. It is not commonly known when jQuery is used in normal web development but pair it with the jQuery Mobile and all hell breaks loose. Through recent years jQuery provided us with several functions meant for an event binding:
     
     
    None of them will check if given event is already binded. jQuery Mobile works in a different way than classic web applications. Depending on how you managed to bind your events each time you visit some page it will bind events over and over. This is not an error, it is simply how jQuery Mobile handles its pages. For example, take a look at this code snipet:
     
    $(document).on('pagebeforeshow','#index' ,function(e,data){    
        $(document).on('click', '#test-button',function(e) {
            alert('Button click');
        });    
    });
    
     
    Each time you visit page #index click event will is going to be bound to button #test-button. Test it by moving from page 1 to page 2 and back several times.
     
    jsFiddle example: http://jsfiddle.net/Gajotres/CCfL4/
     
     
    Several solutions exist to prevent this from happening.
     

    Solution 1


     
     
    Easiest solution would be to use pageinit for event binding. If you take a look at an official documentation you will find out that pageinit will trigger only once, just like document ready, so there’s no way events will be bound again. Unfortunately, there’s one little thing not mentioned in the official documentation.
     
    Pageinit will trigger only once if used in multipage template, if multi-HTML is used pageinit will trigger every time page is loaded into the DOM (more information can be found here and here).
     
    jsFiddle example: http://jsfiddle.net/Gajotres/AAFH8/
     
     

    Solution 2


     
     
    Second solution requires is also an easy one. Before an event is bind you should try to unbind it. Every function used for even binding has a similar function used for event removal (you will find them enumerated at the beginning of this article, every binding function is coupled with a related removal function). Use this solution if first one is not suitable, mostly because it more complex and demanding.
     
    jsFiddle example: http://jsfiddle.net/Gajotres/K8YmG/
     
     
     

    Solution 3


     
     
    Third solution uses nifty jQuery plugin called “Event filter”. Use it like this:
     
    $('#carousel div:Event(!click)').each(function(){
        //If click is not bind to #carousel div do something
    });
    
     
    This filter can be found here: http://www.codenothing.com/archives/2009/event-filter/
     

    Solution 4


     
     
    This is almost easiest solution to implement.
     
    $(document).on('pagebeforeshow', '#index', function(){       
        $(document).on('click', '#test-button',function(e) {
            if(e.handled !== true) // This will prevent event triggering more then once
            {
                alert('Clicked');
                e.handled = true;
            }
        }); 
    });
    
     
    Javascript is used to check if an event is already been triggered. I don’t prefer this solution because it will not stop event binding process, it will just prevent multiple even execution.
     
    jsFiddle example: http://jsfiddle.net/Gajotres/Yerv9/
     
     
    Note Solution found here: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
     
     

    14 COMMENTS

    1. Wow.. nice one.

      I’ve had this error before, don’t remember ho I handled it, but I know it was tricky.
      I even tried using the native javascript “onload” to wrap my jquery events, but It still happened anyway.

      This is a really good way to work around it.

      Thanks Dragan.

    2. Thanks for this! I used second solution and it works great! Your post is a fantastic collction of useful solutions.

    3. I used Solution #4 which was perfect for my needs. I couldn’t figure out for the life of me why my submit button within my partial view was executing twice. This solution solved my problem easy. Thanks!

    Leave a Reply


    six × three =