Search code examples
jquery-mobilejqueryjquery-mobile-listview

jQuery mobile listview multiple click event


I fill list dynamically, and after that on click I have multiple calls of event. 1st time it is repeated 1 time, 2nd time 2 times, 3rd time 3 times, etc...


Solution

  • First, more about this problem can be found in my other answer: jQuery Mobile: document ready vs page events

    Prevent multiple event binding/triggering

    Because of interesting jQM loading architecture, multiple event triggering is a constant problem. 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');
        });    
    });
    

    Working jsFiddle example: http://jsfiddle.net/Gajotres/CCfL4/

    Each time you visit page #index click event will is going to be bound to button #test-button. There are few ways to prevent this problem:

    Solution 1:

    Remove event before you bind it:

    $('#index').live('pagebeforeshow',function(e,data){    
        $('#test-button').die().live('click', function(e) {
            alert('Button click');
        });    
    });
    

    Working jsFiddle example: http://jsfiddle.net/Gajotres/K8YmG/

    In case you have different events bound to an object:

    $('#index').live('pagebeforeshow',function(e,data){    
        $('#test-button').die('click').live('click', function(e) {
            alert('Button click');
        });    
    });
    

    Solution 2:

    Use a jQuery Filter selector, like this:

    $('#carousel div:Event(!click)').each(function(){
        //If click is not bind to #carousel div do something
    });
    

    Because event filter is not a part of official jQuery framework it can be found here: http://www.codenothing.com/archives/2009/event-filter/

    In a nutshell, if speed is your main concern then Solution 2 is much better then Solution 1.

    Solution 3:

    A new one, probably an easiest of them all.

    $(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;
            }
        }); 
    });
    

    Working jsFiddle example: http://jsfiddle.net/Gajotres/Yerv9/

    Tnx to the sholsinger for this solution: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/

    More info

    If you want to find more about this problem take a look at this article, working examples are included.