Javascript 多次触发 jQuery 单击事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14969960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery click events firing multiple times
提问by Gregory Fowler
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.
我正在尝试用 Javascript 编写一个视频扑克游戏,作为了解它的基础知识的一种方式,但我遇到了一个问题,即 jQuery click 事件处理程序多次触发。
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 ithterm of the sequence is for the betting of the ithhand 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. :)
它们附在用于下注的按钮上,在游戏过程中在第一手牌上下注时效果很好(仅触发一次);但是在为第二手牌下注时,每次按下下注或下注按钮时,它都会触发两次 click 事件(因此每次按下时下注正确金额的两倍)。总的来说,当按下下注按钮一次时,点击事件被触发的次数遵循这种模式——序列的第 i项是从游戏开始时第 i手的下注:1, 2, 4 , 7, 11, 16, 22, 29, 37, 46,这似乎是 n(n+1)/2 + 1 对于任何值得的东西——我不够聪明,无法弄清楚,我使用了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
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).
如果您有任何想法或建议,或者我的问题的解决方案与此处另一个问题的解决方案相似,请告诉我(我查看了许多类似标题的线程,但没有找到可行的解决方案为了我)。
回答by Rob
To make sure a click only actions once use this:
要确保仅单击一次操作,请使用以下命令:
$(".bet").unbind().click(function() {
//Stuff
});
回答by mtl
.unbind()is deprecated and you should use the .off()method instead. Simply call .off()right before you call .on().
.unbind()已弃用,您应该改用该.off()方法。只需.off()在您致电之前立即致电.on()。
This will remove all event handlers:
这将删除所有事件处理程序:
$(element).off().on('click', function() {
// function body
});
To only remove registered 'click' event handlers:
仅删除已注册的“点击”事件处理程序:
$(element).off('click').on('click', function() {
// function body
});
回答by Shaunak D
.one()
。一()
A better option would be .one():
更好的选择是.one():
The handler is executed at most once per element per event type.
每个事件类型的每个元素最多执行一次处理程序。
$(".bet").one('click',function() {
//Your function
});
In case of multiple classes and each class needs to be clicked once,
在多个类的情况下,每个类都需要点击一次,
$(".bet").on('click',function() {
//Your function
$(this).off('click'); //or $(this).unbind()
});
回答by Alfonse Pinto
If you find that .off() .unbind() or .stopPropagation() still doesn't fix your specific issue, try using .stopImmediatePropagation()Works great in situations when you just want your event to be handled without any bubbling and without effecting any other events already being handled. Something like:
如果您发现 .off() .unbind() 或 .stopPropagation() 仍然不能解决您的特定问题,请尝试使用.stopImmediatePropagation()在您只想处理事件而没有任何冒泡且没有任何冒泡的情况下效果很好影响已经处理的任何其他事件。就像是:
$(".bet").click(function(event) {
event.stopImmediatePropagation();
//Do Stuff
});
does the trick!
有诀窍!
回答by Pointy
If you're calling that function on each "click", then it's addinganother 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.
使用 jQuery 添加处理程序与设置“onclick”属性的值不同。可以根据需要添加任意数量的处理程序。
回答by Kalpesh Popat
an Event will fire multiple time when it is registered multiple times (even if to the same handler).
当一个事件被多次注册时(即使是同一个处理程序),它会多次触发。
eg $("ctrl").on('click', somefunction)if this piece of code is executed every time the page is partially refreshed, the event is being registered each time too. Hence even if the ctrl is clicked only once it may execute "somefunction" multiple times - how many times it execute will depend on how many times it was registered.
例如,$("ctrl").on('click', somefunction)如果每次页面部分刷新时都执行这段代码,则每次也会注册该事件。因此,即使 ctrl 只被点击一次,它也可能多次执行“某个功能”——它执行的次数将取决于它被注册的次数。
this is true for any event registered in javascript.
对于在 javascript 中注册的任何事件都是如此。
solution:
解决方案:
ensure to call "on" only once.
确保只调用一次“on”。
and for some reason if you cannot control the architecture then do this:
出于某种原因,如果您无法控制架构,请执行以下操作:
$("ctrl").off('click');
$("ctrl").on('click', somefunction);
$("ctrl").off('click');
$("ctrl").on('click', somefunction);
回答by Bobz
I had a problem because of markup.
由于标记,我遇到了问题。
HTML:
HTML:
<div class="myclass">
<div class="inner">
<div class="myclass">
<a href="#">Click Me</a>
</div>
</div>
</div>
jQuery
jQuery
$('.myclass').on('click', 'a', function(event) { ... } );
You notice I have the same class 'myclass' twice in html, so it calls click for each instance of div.
您注意到我在 html 中有两次相同的类“myclass”,因此它为每个 div 实例调用 click。
回答by arc_shiva
The better option would be using off
更好的选择是使用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>
回答by rikkitikkitumbo
All the stuff about .on() and .one() is great, and jquery is great.
所有关于 .on() 和 .one() 的东西都很棒,而 jquery 也很棒。
But sometimes, you want it to be a little more obvious that the user isn't allowed to click, and in those cases you could do something like this:
但有时,您希望用户不能点击更明显一点,在这种情况下,您可以执行以下操作:
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);
}
and your button would look like:
你的按钮看起来像:
<button onclick='funName()'>Click here</button>

