jQuery click events firing multiple times

2018-12-31 18:42发布

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).

20条回答
笑指拈花
2楼-- · 2018-12-31 18:57

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.

查看更多
浪荡孟婆
3楼-- · 2018-12-31 18:58

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.

查看更多
与君花间醉酒
4楼-- · 2018-12-31 19:01

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();
查看更多
情到深处是孤独
5楼-- · 2018-12-31 19:02

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.

查看更多
查无此人
6楼-- · 2018-12-31 19:02

Try that way:

<a href="javascript:void(0)" onclick="this.onclick = false; fireThisFunctionOnlyOnce()"> Fire function </a>
查看更多
刘海飞了
7楼-- · 2018-12-31 19:05

its an old issue, but i faced it today, and i think my answer will help for future seeker of similar challenges.

it is executed multiple times, because the "on('click', somefunction)" function is being called multiple times and hence it gets binded multiple times - to permanently solve this, you need to ensure that "on" function is in such a place that it will only be executed once. after which on the mouse click event, the function will be fired only once.

for example if i put "on('click', somefunction)" in a place where it will be loaded twice, then on every click - "somefunction" will be fired twice.

in a correct logical sequence "off" function should be used only when you really intend to unbind the events. to use it for hiding the logical errors caused due to double loading of "on" function, is not a good approach even if it may seem to be working.

查看更多
登录 后发表回答