jQuery click events firing multiple times

JavascriptJqueryClickJquery Events

Javascript Problem Overview


I'm attempting to write a video poker game in Javascript as a way of getting the basics of it down, and I've run into a problem where the jQuery click event handlers are firing multiple times.

They're attached to buttons for placing a bet, and it works fine for placing a bet on the first hand during a game (firing only once); but in betting for the second hand, it fires the click event twice each time a bet or place bet button is pressed (so twice the correct amount is bet for each press). Overall, it follows this pattern for number of times the click event is fired when pressing a bet button once--where the ith term of the sequence is for the betting of the ith hand from the beginning of the game: 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, which appears to be n(n+1)/2 + 1 for whatever that's worth--and I wasn't smart enough to figure that out, I used OEIS. :)

Here's the function with the click event handlers that are acting up; hopefully it's easy to understand (let me know if not, I want to get better at that as well):

/** The following function keeps track of bet buttons that are pressed, until place button is pressed to place bet. **/
function pushingBetButtons() {
    $("#money").text("Money left: $" + player.money); // displays money player has left

    $(".bet").click(function() {
	    var amount = 0; // holds the amount of money the player bet on this click
	    if($(this).attr("id") == "bet1") { // the player just bet $1
		    amount = 1;
	    } else if($(this).attr("id") == "bet5") { // etc.
		    amount = 5;
	    } else if($(this).attr("id") == "bet25") {
		    amount = 25;
	    } else if($(this).attr("id") == "bet100") {
		    amount = 100;
	    } else if($(this).attr("id") == "bet500") {
		    amount = 500;
	    } else if($(this).attr("id") == "bet1000") {
		    amount = 1000;
	    }
	    if(player.money >= amount) { // check whether the player has this much to bet
		    player.bet += amount; // add what was just bet by clicking that button to the total bet on this hand
		    player.money -= amount; // and, of course, subtract it from player's current pot
		    $("#money").text("Money left: $" + player.money); // then redisplay what the player has left
	    } else {
		    alert("You don't have $" + amount + " to bet.");
	    }
    });

    $("#place").click(function() {
	    if(player.bet == 0) { // player didn't bet anything on this hand
		    alert("Please place a bet first.");
	    } else {
		    $("#card_para").css("display", "block"); // now show the cards
		    $(".card").bind("click", cardClicked); // and set up the event handler for the cards
		    $("#bet_buttons_para").css("display", "none"); // hide the bet buttons and place bet button
		    $("#redraw").css("display", "block"); // and reshow the button for redrawing the hand
		    player.bet = 0; // reset the bet for betting on the next hand
		    drawNewHand(); // draw the cards
	    }
    });
}

Please let me know if you have any ideas or suggestions, or if the solution to my problem is similar to a solution to another problem on here (I've looked at many similarly titled threads and had no luck in finding a solution that could work for me).

Javascript Solutions


Solution 1 - Javascript

To make sure a click only actions once use this:

$(".bet").unbind().click(function() {
    //Stuff
});

Solution 2 - Javascript

.unbind() is deprecated and you should use the .off() method instead. Simply call .off() right before you call .on().

This will remove all event handlers:

$(element).off().on('click', function() {
    // function body
});

To only remove registered 'click' event handlers:

$(element).off('click').on('click', function() {
    // function body
});

Solution 3 - Javascript

.one()

A better option would be .one() :

>The handler is executed at most once per element per event type.

$(".bet").one('click',function() {
    //Your function
});

In case of multiple classes and each class needs to be clicked once,

$(".bet").on('click',function() {
    //Your function
    $(this).off('click');   //or $(this).unbind()
});

Solution 4 - Javascript

If you find that .off() .unbind() or .stopPropagation() still doesn't fix your specific issue, try using [.stopImmediatePropagation()][1] Works great in situations when you just want your event to be handled without any bubbling and without effecting any other events already being handled. Something like:

$(".bet").click(function(event) {
  event.stopImmediatePropagation();
  //Do Stuff
});

does the trick! [1]: http://api.jquery.com/event.stopImmediatePropagation/

Solution 5 - Javascript

If you're calling that function on each "click", then it's adding another pair of handlers on each call.

Adding handlers with jQuery just isn't like setting the value of the "onclick" attribute. One can add as many handlers as one desires.

Solution 6 - Javascript

an Event will fire multiple time when it is registered multiple times (even if to the same handler).

eg $("ctrl").on('click', somefunction) if this piece of code is executed every time the page is partially refreshed, the event is being registered each time too. Hence even if the ctrl is clicked only once it may execute "somefunction" multiple times - how many times it execute will depend on how many times it was registered.

this is true for any event registered in javascript.

solution:

ensure to call "on" only once.

and for some reason if you cannot control the architecture then do this:

$("ctrl").off('click'); $("ctrl").on('click', somefunction);

Solution 7 - Javascript

$('.bed').one(function(){ })

Docs:

http://api.jquery.com/one/

Solution 8 - Javascript

We must to stopPropagation() In order to avoid Clicks triggers event too many times.

$(this).find('#cameraImageView').on('click', function(evt) {
   evt.stopPropagation();
   console.log("Camera click event.");
});

It Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event. This method does not accept any arguments.

We can use event.isPropagationStopped() to determine if this method was ever called (on that event object).

This method works for custom events triggered with trigger(), as well.Note that this will not prevent other handlers on the same element from running.

Solution 9 - Javascript

I had a problem because of markup.

HTML:

<div class="myclass">
 <div class="inner">

  <div class="myclass">
   <a href="#">Click Me</a>
  </div>

 </div>
</div>

jQuery

$('.myclass').on('click', 'a', function(event) { ... } );

You notice I have the same class 'myclass' twice in html, so it calls click for each instance of div.

Solution 10 - Javascript

When I deal with this issue, I always use:

$(".bet").unbind("click").bind("click", function (e) {
  // code goes here
}

This way I unbind and rebind in the same stroke.

Solution 11 - Javascript

The better option would be using off

<script>
function flash() {
  $("div").show().fadeOut("slow");
}
$("#bind").click(function() {
  $( "body" )
    .on("click", "#theone", flash)
    .find("#theone")
      .text("Can Click!");
});
$("#unbind").click(function() {
  $("body")
    .off("click", "#theone", flash)
    .find("#theone")
      .text("Does nothing...");
});
</script>

Solution 12 - Javascript

All the stuff about .on() and .one() is great, and jquery is great.

But sometimes, you want it to be a little more obvious that the user isn't allowed to click, and in those cases you could do something like this:

function funName(){
	$("#orderButton").prop("disabled", true);
    // 	do a bunch of stuff
	// and now that you're all done
	setTimeout(function(){
		$("#orderButton").prop("disabled",false);
		$("#orderButton").blur();
	}, 3000);
}

and your button would look like:

<button onclick='funName()'>Click here</button>

Solution 13 - Javascript

It happens due to the particular event is bound multiple times to the same element.

The solution which worked for me is:

Kill all the events attached using .die() method.

And then attach your method listener.

Thus,

$('.arrow').click(function() {
// FUNCTION BODY HERE
}

should be:

$('.arrow').die("click")
$('.arrow').click(function() {
// FUNCTION BODY HERE
}

Solution 14 - Javascript

In my case I was using 'delegate', so none of these solutions worked. I believe it was the button appearing multiple times via ajax calls that was causing the multiple click issue. The solutions was using a timeout so only the last click is recognized:

var t;
$('body').delegate( '.mybutton', 'click', function(){
    // clear the timeout
    clearTimeout(t);
    // Delay the actionable script by 500ms
    t = setTimeout( function(){
        // do something here
    },500)
})

Solution 15 - Javascript

$(element).click(function (e)
{
  if(e.timeStamp !== 0) // This will prevent event triggering more then once
   {
      //do your stuff
   }
}

Solution 16 - Javascript

.one only fires once for the lifetime of the page

So in case you want to do validation, this is not the right solution, because when you do not leave the page after validation, you never come back. Better to use

$(".bet").on('click',function() 
{ //validation 
   if (validated) { 
      $(".bet").off('click'); //prevent to fire again when we are not yet off the page
      //go somewhere
    }
});

Solution 17 - Javascript

I was having this problem with a dynamically generated link:

$(document).on('click', '#mylink', function({...do stuff...});

I found replacing document with 'body' fixed the issue for me:

$('body').on('click', '#mylink', function({...do stuff...});

Solution 18 - Javascript

https://jsfiddle.net/0vgchj9n/1/

To make sure the event always only fires once, you can use Jquery .one() . JQuery one ensures that your event handler only called once. Additionally, you can subscribe your event handler with one to allow further clicks when you have finished the processing of the current click operation.

<div id="testDiv">
  <button class="testClass">Test Button</button>
</div>

var subscribeClickEvent = function() {$("#testDiv").one("click", ".testClass", clickHandler);};

function clickHandler() {
  //... perform the tasks  
  alert("you clicked the button");
  //... subscribe the click handler again when the processing of current click operation is complete  
  subscribeClickEvent();
}

subscribeClickEvent();

Solution 19 - Javascript

Try that way:

<a href="javascript:void(0)" onclick="this.onclick = false; fireThisFunctionOnlyOnce()"> Fire function </a>

Solution 20 - Javascript

In my case, onclick event was firing multiple times coz I had made a generic event handler comparatively as

  `$('div').on("click", 'a[data-toggle="tab"]',function () {
		console.log("dynamic bootstrap tab clicked");
		var href = $(this).attr('href');
		window.location.hash = href;
   });`

changed to

    `$('div#mainData').on("click", 'a[data-toggle="tab"]',function () {
		console.log("dynamic bootstrap tab clicked");
		var href = $(this).attr('href');
		window.location.hash = href;
	});`

and also have to make separate handlers for static and dynamic clicks, for static tab click

    `$('a[data-toggle="tab"]').on("click",function () {
		console.log("static bootstrap tab clicked");
		var href = $(this).attr('href');
		window.location.hash = href;
	});`

Solution 21 - Javascript

In my case I had loaded the same *.js file on the page twice in a <script> tag, so both files were attaching event handlers to the element. I removed the duplicate declaration and that fixed the problem.

Solution 22 - Javascript

Another solution I found was this, if you have multiple classes and are dealing with radio buttons while clicking on the label.

$('.btn').on('click', function(e) {
	e.preventDefault();
    
	// Hack - Stop Double click on Radio Buttons
	if (e.target.tagName != 'INPUT') {
		// Not a input, check to see if we have a radio
		$(this).find('input').attr('checked', 'checked').change();
    }
});

Solution 23 - Javascript

In case this works fine

$( "#ok" ).bind( "click", function() {
    console.log("click"); 
});

Solution 24 - Javascript

Reference @Pointy answer. if this in loop, one can avoid click events firing multiple times by doing something like this:

 $(".bet").each(function(i,item){
       $(this).on({
            click:function(){
                //TRIGGERS ONES
            if(i){
              console.log(i); 
                //DO YOUR THING HERE
            }
            
            }
        });

});

Solution 25 - Javascript

use Event.stopPropagation(). It will work.

Solution 26 - Javascript

The below code worked for me in my chat application to handle multiple mouse click triggering events more than once. if (!e.originalEvent.detail || e.originalEvent.detail == 1) { // Your code logic }

Solution 27 - Javascript

Unbind () works, but that might cause other issues in the future. The handler triggers multiple times when it is inside another handler, so keep your handler outside and if you want the values of the handler which had nested, assign them to a global variable that it will be accessible to the your handler.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGregory FowlerView Question on Stackoverflow
Solution 1 - JavascriptRobView Answer on Stackoverflow
Solution 2 - JavascriptmtlView Answer on Stackoverflow
Solution 3 - JavascriptShaunak DView Answer on Stackoverflow
Solution 4 - JavascriptAlfonse PintoView Answer on Stackoverflow
Solution 5 - JavascriptPointyView Answer on Stackoverflow
Solution 6 - JavascriptKalpesh PopatView Answer on Stackoverflow
Solution 7 - JavascriptConner GesbockerView Answer on Stackoverflow
Solution 8 - JavascriptDaniel Raja SinghView Answer on Stackoverflow
Solution 9 - JavascriptBobzView Answer on Stackoverflow
Solution 10 - JavascriptAndyView Answer on Stackoverflow
Solution 11 - Javascriptarc_shivaView Answer on Stackoverflow
Solution 12 - JavascriptrikkitikkitumboView Answer on Stackoverflow
Solution 13 - JavascriptPupilView Answer on Stackoverflow
Solution 14 - JavascriptTrevor LettmanView Answer on Stackoverflow
Solution 15 - JavascriptRajan Rajan MView Answer on Stackoverflow
Solution 16 - JavascriptPieter van KampenView Answer on Stackoverflow
Solution 17 - JavascriptnateMView Answer on Stackoverflow
Solution 18 - JavascriptRazan PaulView Answer on Stackoverflow
Solution 19 - JavascriptAdam KozlowskiView Answer on Stackoverflow
Solution 20 - JavascriptMuhammad AwaisView Answer on Stackoverflow
Solution 21 - JavascriptinostiaView Answer on Stackoverflow
Solution 22 - JavascriptAndrew VinkView Answer on Stackoverflow
Solution 23 - Javascriptsantosh vishwakarmaView Answer on Stackoverflow
Solution 24 - JavascriptShapCyberView Answer on Stackoverflow
Solution 25 - JavascriptDanView Answer on Stackoverflow
Solution 26 - Javascriptuser2792303View Answer on Stackoverflow
Solution 27 - Javascriptpraveen poonjaView Answer on Stackoverflow