jQuery点击事件触发多次

349
我正在尝试用Javascript编写一个视频扑克游戏,以此来掌握其基础知识,但我遇到了一个问题:jQuery点击事件处理程序会多次触发。它们附加在下注按钮上,在第一局游戏中下注时可以正常工作(仅触发一次);但是在下注第二手牌时,每次按下下注或放置下注按钮都会触发两次点击事件(因此每次按下将下注两倍的正确金额)。总体而言,当只按下一次下注按钮时,它遵循以下模式触发点击事件的次数,其中序列的第i项是从游戏开始时第i个手牌的下注:1、2、4、7、11、16、22、29、37、46,这似乎是n(n+1)/2 + 1,无论值不值得,我都不够聪明去理解它,我使用了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
        }
    });
}

请告诉我您是否有任何想法或建议,或者如果解决我的问题的方法类似于此处另一个问题的解决方法(我查看了许多标题类似的线程,但没有找到适合我的解决方案)。


var amount = parseInt(this.id.replace(/[^\d]/g,''),10);如果您将要多次使用元素的同一属性,请缓存该属性,不要一直重新查找。这种查找是很昂贵的。 - David Thomas
谢谢您的回复,以及有关缓存属性的提示。我在该函数内将player.money和player.bet设置为本地变量money和bet,并对其进行操作,我将更改我的其余代码以执行此操作。:) 如果您有时间,还可以解释一下您建议的amount初始化是做什么的;它看起来像一些正则表达式,但我很难理解它的含义。 - Gregory Fowler
@GregoryFowler - 和你的问题无关,但是……可能值得研究一下 JavaScript 的 switch 语句。 - Clayton
2
兄弟,你的函数每次被调用都会放置一个点击处理程序。如果你在每个回合中调用它,在第二个回合中你就有两个处理程序,依此类推。每个处理程序都会执行其工作,到第100轮时你将获得100个警报。 - Marco Faustinelli
这��因为在你的代码中,某处重新绑定了事件处理程序而没有先解除绑定。请参考此问题以获取类似情况的详细说明 - jpaugh
可能是点击事件触发多次问题,如何解决?的重复问题。 - jpaugh
29个回答

0

这个解决方案对我很有用。当您的元素是动态添加的时候,您需要按照这种方式来实现它。这个答案可能是为了未来检查用户而提供的。

$("body").off("click", ".Element").on("click", ".Element", function(e){
     e.preventDefault();
    //Your code here 
}); 

0
在我的情况下,我在页面上两次加载了相同的*.js文件,并在<script>标签中附加了事件处理程序,因此两个文件都会将事件处理程序附加到元素。我删除了重复声明,问题得到解决。

0

使用 Event.stopPropagation()。它会起作用。


0
如果你只写这个: $(document).off('click').on("click", "#btnID", function(){ })
那么,它将禁用所有项目的点击事件。
如果你只想关闭特定按钮的点击事件,请这样做 $(document).off('click', "#btnID").on("click", "#btnID", function(){ })

0
我发现的另一个解决方案是,如果您有多个类并且在单击标签时处理单选按钮。
$('.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();
    }
});

0
尝试这个方法:
<a href="javascript:void(0)" onclick="this.onclick = false; fireThisFunctionOnlyOnce()"> Fire function </a>

0

如果这个正常工作

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

-1

Unbind() 可以解决问题,但这可能会在未来引起其他问题。当处理程序位于另一个处理程序内部时,处理程序会触发多次,因此请将您的处理程序放在外部,并且如果您想要嵌套的处理程序的值,则将它们分配给全局变量,以便您的处理程序可以访问它们。


-1
以下代码在我的聊天应用程序中可以处理多次触发鼠标单击事件。 if (!e.originalEvent.detail || e.originalEvent.detail == 1) { // Your code logic }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接