jQuery点击多次触发事件
我正在尝试用Javascript编写一个video扑克游戏作为获取它的基础知识的一种方式,并且遇到了jQuery click事件处理程序多次触发的问题。
他们附在button上进行下注,在游戏中第一手下注(适用于一次),可以正常工作。 但是在下注二手牌时,每次按下投注或投注button时都会触发点击事件两次(所以每次按下投注正确的金额两次)。 总的来说,按下一次下注button后点击事件被触发的次数就是这种模式 – 序列的第i项是从游戏开始时第i只手的下注:1,2,4 ,7,11,16,22,29,37,46,看起来是n(n + 1)/ 2 + 1,因为任何值得的东西 – 我还不够聪明,所以我用OEIS 。 🙂
以下是正在执行的点击事件处理程序的function。 希望这很容易理解(如果没有,请告诉我,我也希望在这方面做得更好):
/** 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 } }); }
请让我知道,如果你有任何想法或build议,或者如果我的问题的解决scheme类似于解决scheme到另一个问题在这里(我已经看了很多类似的标题线程,并没有find一个可以工作的解决scheme的运气为了我)。
为了确保一次点击操作使用此操作:
$(".bet").unbind().click(function() { //Stuff });
.unbind()
已被弃用,您应该使用.off()
方法。 在调用.on()
之前,只需调用.on()
。
这将删除所有事件处理程序:
$(element).off().on('click', function() { // function body });
只删除注册的“点击”事件处理程序:
$(element).off('click').on('click', function() { // function body });
。一()
更好的select是.one()
:
处理程序每个事件types每个元素最多执行一次。
$(".bet").one('click',function() { //Your function });
如果有多个class级,每个class级需要点击一次,
$(".bet").on('click',function() { //Your function $(this).off('click'); //or $(this).unbind() });
如果您发现.off().unbind()或.stopPropagation()仍然不能解决您的特定问题,请尝试使用.stopImmediatePropagation()在只想要处理没有冒泡的情况下影响已经处理的任何其他事件。 就像是:
$(".bet").click(function(event) { event.stopImmediatePropagation(); //Do Stuff });
诀窍!
如果您在每次“点击”时调用该函数,则在每次调用中都会添加另一对处理程序。
用jQuery添加处理程序只是不像设置“onclick”属性的值。 可以根据需要添加尽可能多的处理程序。
这是一个老问题,但我今天面对这个问题,我想我的答案将有助于未来寻求类似挑战的人。
它会被执行多次,因为“on('click',somefunction)”函数被多次调用,因此被多次绑定 – 为了永久解决这个问题,你需要确保“on”函数是这样的它只会被执行一次。 之后在鼠标单击事件上,该函数只会被触发一次。
例如,如果我把它放在一个将被加载两次的地方,然后每次点击“somefunction”将会被触发两次。
在正确的逻辑顺序中,只有当你打算解除事件时,才应该使用“关”function。 使用它来隐藏由于“on”函数的双重加载而引起的逻辑错误,即使它看起来可能正在工作也不是一个好方法。
由于标记,我有一个问题。
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) { ... } );
你注意到我有两个相同的类'myclass'在html中,所以它调用点击每个div的实例。
这是由于特定的事件绑定了多次到同一个元素。
为我工作的解决scheme是:
使用.die()
方法杀死所有附加的事件。
然后附上您的方法侦听器。
从而,
$('.arrow').click(function() { // FUNCTION BODY HERE }
应该:
$('.arrow').die("click") $('.arrow').click(function() { // FUNCTION BODY HERE }
我们必须stopPropagation()
为了避免Clicks触发事件太多次。
$(this).find('#cameraImageView').on('click', function(evt) { evt.stopPropagation(); console.log("Camera click event."); });
它阻止事件冒泡DOM树,阻止任何父处理程序被通知事件。 此方法不接受任何参数。
我们可以使用event.isPropagationStopped()
来确定这个方法是否曾被调用(在该事件对象上)。
此方法也适用于由trigger()触发的自定义事件。请注意,这不会阻止同一元素上的其他处理程序运行。
更好的select是使用closures
<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>
所有关于.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看起来像:
<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 } }
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();
在我的情况下,我使用“委托”,所以这些解决scheme都没有工作。 我相信这是button出现多次通过Ajax调用导致多个点击问题。 解决scheme是使用超时,所以只有最后一次点击被识别:
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) })