我试图在Javascript中编写一个视频扑克游戏,作为一种获得它的基础知识的方式,我遇到了一个问题,jQuery点击事件处理程序被多次触发。

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

这是一个点击事件处理程序的函数;希望这很容易理解(如果不容易,请告诉我,我也想在这方面做得更好):

/** 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
        }
    });
}

如果你有任何想法或建议,或者我的问题的解决方案与这里的另一个问题的解决方案相似,请告诉我(我看过许多类似标题的帖子,但没有幸运地找到一个适合我的解决方案)。


当前回答

我们必须停止传播(),以避免点击触发事件太多次。

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

它阻止事件冒泡到DOM树,防止任何父处理程序被通知该事件。此方法不接受任何参数。

我们可以使用event. ispropagationstopped()来确定这个方法是否被调用过(在该事件对象上)。

此方法也适用于由trigger()触发的自定义事件。注意,这不会阻止同一元素上的其他处理程序运行。

其他回答

参考@尖锐的回答。如果在循环中,可以通过这样做避免多次触发单击事件:

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

});

Unbind()有效,但将来可能会导致其他问题。处理程序在另一个处理程序内部时会触发多次,所以让你的处理程序在外部,如果你想要嵌套的处理程序的值,将它们分配给一个全局变量,它将被你的处理程序访问。

我发现的另一个解决方案是,如果你有多个类,并且在单击标签时处理单选按钮。

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

试试这个方法:

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

.在页面的生命周期中只触发一次

因此,如果您想进行验证,这不是正确的解决方案,因为当您在验证后不离开页面时,您就永远不会回来。更好地使用

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