Preventing double event binding in jQuery

1.5k Views Asked by At

I have this code

$(".generate").click(function() {
    $.getJSON("jsonfile.json").done(function(data) {

        if (parseInt(data)>0) {
            $(".mybutton").click(function() {
               alert(data); 
            });
        }

    });
});

When the "generate" button is clicked, the getJSON function is called and if data says "ok" then I can press the "mybutton" to alert the data;

Only problem is if I press the "generate" button a few times (I want this to happen), the "mybutton" will alert "hello" also a number of times (depending on how many times I clicked the generate button).

I have tried e.stopPropagation(), but this did not help.

5

There are 5 best solutions below

0
On BEST ANSWER

The reason is that every time you click the button .generate you add a new event handler on the element with the class .mybutton

It's not very clear what you're trying to do, but if the purpose is to store the data you get from the ajax call, you can do like this:

//data container
var localData;

//will show the actual content of the variable when .mybutton is clicked
$(".mybutton").click(function()
{
    alert(localData);
});

//this will update the variable when .generate is clicked
$(".generate").click(function() 
{
    $.getJSON("jsonfile.json").done(function(data) 
    {
        if (parseInt(data)>0)
        {
            localData = data; 

            //this will trigger the click event on the button .mybutton that will fire the handler with the alert
            $(".mybutton").trigger('click'); 
        }
    });
});
3
On

Use delegation with on() like

    $(function() {
     var buttonData = {};
     $(".generate").click(function() {
         $.getJSON("jsonfile.json").done(function(data) {

             if (parseInt(data) > 0) {
                 buttonData = data;
             }

         });
     });
     $(document).on('click', '.mybutton', function() {
         alert(buttonData);
     });
 });

and bind it outside of the getJSON success handler

0
On

You could unbind and re-bind the handler each time

if (parseInt(data)>0) {
    $(".mybutton").off('click').click(function() {
       alert(data); 
    });
}
0
On

What if you try it this way? (Didn't test this, but should work)

$(".generate").click(function() {
   $(this).unbind('click').next()
    $.getJSON("jsonfile.json").done(function(data) {

        if (parseInt(data)>0) {
            $(".mybutton").click(function() {
               $(this).unbind('click').next()
               alert(data); 
            });
        }

    });
});
0
On

Why do you always rebind the event. Is the button removed from the DOM after you click the generate button?

If not you could only bind the event once and just disable the button while no data is available:

$(".mybutton").prop('disabled', true); // initially disable
$(".mybutton").click(function() { // bind the event once
    alert(data); 
});

$(".generate").click(function() {
    $(".mybutton").prop('disabled', true); // disable if new data starts to generate
    $.getJSON("jsonfile.json").done(function(data) {

       if (parseInt(data)>0) {
           $(".mybutton").prop('disabled', false); // enable if everything is ok
       }
   });  
});