その基本を理解するためにJavascriptでビデオポーカーゲームを作成しようとしていますが、jQueryのクリックイベントハンドラが複数回起動されるという問題に遭遇しました。
それらは賭けをするためのボタンに付けられていて、ゲーム中に最初に賭けをするのにうまく働きます(一度だけ発射する)。しかし、セカンドハンドへのベットでは、ベットボタンまたはプレースベットボタンが押されるたびにクリックイベントが2回発生します(つまり、各プレスで正しい金額の2倍がベットされます)。概して、それはベットボタンを一回押すときクリックイベントが発生する回数の間このパターンに従います - ここでシーケンスのi項はi手の賭けのためのものです1、2、4、7、11、16、22、29、37、46、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
}
});
}
何かアイデアや提案がある場合、または私の問題の解決策がこちらの別の問題の解決策に似ているかどうかを教えてください(私は似たようなタイトルのスレッドをたくさん見ましたが、うまくいく解決策を見つけられませんでした)私のために)。
クリックのみのアクションを確実にするには、これを一度使用します。
$(".bet").unbind().click(function() {
//Stuff
});
.unbind()
は非推奨であり、代わりに .off()
メソッドを使用してください。 .off()
を呼び出す直前に、単に.on()
を呼び出してください。
これにより、すべてのイベントハンドラが削除されます。
$(element).off().on('click', function() {
// function body
});
登録されたクリックイベントハンドラのみを削除するには:
$(element).off('click').on('click', function() {
// function body
});
それでも.off()、.unbind()、または.stopPropagation()を実行しても問題が解決しない場合は、 .stopImmediatePropagation() を使用してみてください。バブリングすることなく、またすでに処理中の他のイベントに影響を与えることなく処理されます。何かのようなもの:
$(".bet").click(function(event) {
event.stopImmediatePropagation();
//Do Stuff
});
トリックをします!
あなたが "クリック"するたびにその関数を呼んでいるのであれば、それは 追加 それぞれの呼び出しでもう一対のハンドラです。
JQueryでハンドラを追加することは、単に "onclick"属性の値を設定することとは異なります。望むだけの数のハンドラを追加することができます。
それは古い問題ですが、私は今日それに直面しました、そして私の答えは同様の課題の将来の探求者に役立つと思います。
"on( 'click'、somefunction)"関数が複数回呼び出されているため複数回バインドされているため、これは複数回実行されます。一度だけ実行される場所その後、マウスクリックイベントで、関数は一度だけ起動されます。
たとえば、「on( 'click'、somefunction)」を2回読み込まれる場所に配置した場合、クリックするたびに「somefunction」が2回起動されます。
論理的に正しい順序で "off"関数を使うのは、本当にイベントをアンバインドしようとしているときだけにしてください。 "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) { ... } );
私はhtmlで同じクラス 'myclass'を2回持っているので、divの各インスタンスに対してclickを呼び出します。
.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>
より良い方法は 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>
私の場合は「代理人」を使用していたので、これらの解決策はどれもうまくいきませんでした。私はそれがマルチクリックの問題を引き起こしていたのは、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)
})
Clicksがイベントを何度もトリガーしないようにするには、stopPropagation()
を実行する必要があります。
$(this).find('#cameraImageView').on('click', function(evt) {
evt.stopPropagation();
console.log("Camera click event.");
});
イベントがDOMツリーを膨らませるのを防ぎ、親ハンドラにイベントが通知されるのを防ぎます。このメソッドは引数を取りません。
このメソッドが(そのイベントオブジェクトに対して)呼び出されたことがあるかどうかを判断するためにevent.isPropagationStopped()
を使用できます。
このメソッドは、trigger()でトリガーされたカスタムイベントにも機能します。これにより、同じ要素上の他のハンドラーの実行が妨げられることはありません。
特定のイベントが同じ要素に複数回バインドされているために発生します。
私のために働いた解決策は、次のとおりです。
.die()
メソッドを使用して添付されたすべてのイベントを終了させます。
そして、メソッドリスナーを添付してください。
したがって、
$('.arrow').click(function() {
// FUNCTION BODY HERE
}
する必要があります:
$('.arrow').die("click")
$('.arrow').click(function() {
// FUNCTION BODY HERE
}
私がこの問題に取り組むとき、私はいつも使用します:
$(".bet").unbind("click").bind("click", function (e) {
// code goes here
}
このように私はアンバインドし、同じストロークで再バインドします。
$(element).click(function (e)
{
if(e.timeStamp !== 0) // This will prevent event triggering more then once
{
//do your stuff
}
}
.oneはページの存続期間中に一度だけ起動します。
そのため、検証を行いたい場合、これは正しい解決策ではありません。検証後にページを終了しないと、戻ってこないからです。使うほうがいい
$(".bet").on('click',function()
{ //validation
if (validated) {
$(".bet").off('click'); //prevent to fire again when we are not yet off the page
//go somewhere
}
});
あなたが複数のクラスを持っていて、ラベルをクリックしている間にラジオボタンを扱っているならば、私が見つけたもう一つの解決策はこれでした。
$('.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();
}
});
https://jsfiddle.net/0vgchj9n/1/ /
イベントが常に一度だけ発生するようにするには、Jquery .one()を使用します。 JQueryはあなたのイベントハンドラが一度だけ呼び出されることを保証します。さらに、現在のクリック操作の処理が終了したときにさらにクリックできるように、イベントハンドラを1つ登録することができます。
<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();
私は動的に生成されたリンクでこの問題を抱えていました:
$(document).on('click', '#mylink', function({...do stuff...});
document
を'body'
に置き換えると問題が解決しました。
$('body').on('click', '#mylink', function({...do stuff...});
私の場合は、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;
});`
そのようにしてみてください。
<a href="javascript:void(0)" onclick="this.onclick = false; fireThisFunctionOnlyOnce()"> Fire function </a>
私の場合は、同じ*.js
ファイルを<script>
タグでページに2回ロードしていたので、どちらのファイルもイベントハンドラを要素に添付していました。私は重複した宣言を削除して問題を解決しました。