我试图在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
        }
    });
}

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


如果您在每次“单击”时调用该函数,那么它将在每次调用时添加另一对处理程序。

使用jQuery添加处理程序并不像设置“onclick”属性的值。可以根据需要添加任意数量的处理程序。


要确保单击只执行一次操作,请使用以下命令:

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

发生这种情况是因为特定事件多次绑定到同一元素。

对我有效的解决方案是:

使用.die()方法杀死所有附加的事件。

然后附加方法监听器。

因此,

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

应该是:

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

.unbind()已弃用,您应该使用.off()方法代替。只需在调用.on()之前调用.off()即可。

这将删除所有事件处理程序:

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

只删除已注册的'点击'事件处理程序:

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

。()

更好的选择是.one():

每个事件类型的每个元素最多执行一次处理程序。

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

如果有多个类,且每个类需要点击一次,

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

当一个事件被多次注册时,它将被多次触发(即使是同一个处理程序)。

如美元(“ctrl”)。On ('click', somefunction)如果每次页面部分刷新时都执行这段代码,则每次也会注册该事件。因此,即使ctrl只被单击一次,它也可能会执行“somefunction”多次——执行多少次取决于它被注册了多少次。

这对于任何用javascript注册的事件都是正确的。

解决方案:

确保只调用“on”一次。

出于某种原因,如果你不能控制架构,那么就这样做:

$ (" ctrl ") (.off’click’); $ (" ctrl ")。据(’click’somefunction);


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

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

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

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

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


如果你发现.off() .unbind()或. stoppropagation()仍然不能解决你的特定问题,尝试使用. stopimmediatepropagation()在你只是想要你的事件被处理而没有任何冒泡并且不影响任何其他已经被处理的事件的情况下工作得很好。喜欢的东西:

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

真管用!


因为加价,我遇到了一个问题。

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) { ... } );

你注意到我在html中有两次相同的类'myclass',所以它为每个div实例调用click。


更好的选择是使用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>

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

为了确保事件总是只触发一次,可以使用Jquery .one()。JQuery可以确保你的事件处理程序只被调用一次。此外,您还可以订阅一个事件处理程序,以便在完成当前单击操作的处理后允许进一步单击。

<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();

所有关于.on()和.one()的东西都很棒,jquery也很棒。

但有时,你想让它更明显一点,用户不允许点击,在这种情况下,你可以这样做:

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

你的按钮看起来是这样的:

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

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

在我的案例中,我使用的是“委托”,所以这些解决方案都不起作用。我相信这是按钮出现多次通过ajax调用,导致多次点击问题。解决方案是使用超时,所以只有最后一次点击被识别:

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

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

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

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

试试这个方法:

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

在我的情况下,onclick事件被多次触发,因为我已经做了一个通用的事件处理程序比较

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

更改为

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

还必须为静态和动态点击,静态选项卡点击创建单独的处理程序

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

在我的例子中,我用<script>标记在页面上加载了两次相同的*.js文件,所以两个文件都将事件处理程序附加到元素上。我删除了重复的声明,这就解决了问题。


当我处理这个问题时,我总是使用:

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

通过这种方式,我可以在同一笔划中解除绑定并重新绑定。


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

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

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

文档:

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


我有这个问题与动态生成的链接:

美元(文档)。在('点击','#mylink',函数({…做东西…});

我发现用“body”替换文档可以解决这个问题:

美元(的身体)。在('点击','#mylink',函数({…做东西…});


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


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


以防这能正常工作

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

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

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

});

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


这个解决方案对我很有效。当您的元素添加动态时,您需要这样做来实现它。这个答案可能是为将来的用户检查。

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

如果你这样写:

$(文档).off(“点击”)。on("click", "#btnID", function(){})

然后,它将禁用所有项目的单击事件。

如果您只是想关闭单击特定的按钮,请执行此操作

美元(文件)。关掉(“点击”、“# btnID”)。on(点击,btnID,功能)