2016-03-28 22 views
1

確認ボタン(yes-button)が押されたときに関数を呼び出し、別の関数をパラメータとして渡し、別の関数で2つの異なるボタンクリックにバインドするカスタム確認ボックスのコードを書きましたパラメータ。たとえば:すべてが期待どおりに起こるjQueryコールバック関数が累積

$('#button1').click(function() { 
    callFunction(function() { alert("test"); }); 
}); 
$('#button2').click(function() { 
    callFunction(function() { alert("test2"); }); 
}); 

function callFunction(callback) { 
    //code to display custom confirm box 

    console.log(callback); 

    $('.confirm-box .yes-button').click(function() { 
     callback(); 
    }); 
} 

、ボックスが表示され、確認ボタンの上に私が実行するコールバック関数を取得し、それが(確認ボックスと呼ばれたボタンに応じて、または「TEST2」)「test」を警告する]をクリックして確認します。この問題は、「テスト」を警告する関数を送信するbutton1をクリックした後、キャンセルすることを確認する代わりに(期待どおりに何も起こらない)、alert2()をコールバック関数として渡すbutton2をクリックすると発生します。今度は「test2」だけを警告するのではなく、「yes」ボタンを押すと、「test2」と「test」アラートが表示されますが、console.logにはそのボタンの時点で "test2"クリック。これらのコールバック関数はどこかに積み重なっているようですが、どこで、なぜか分かりません。

+0

別の 'click'イベントを宣言するのではなく、グローバルスコープで' callback'を上書きしようとします。 –

+2

イベントハンドラを別のイベントハンドラにバインドするのはほとんど常に間違っています。 – Barmar

答えて

2

.click()関数は、複数のハンドラを要素に追加できますが、ここでは何が起こっているのでしょうか。これを試してください:

これは、新しいクリックハンドラを適用する前に、以前のクリックハンドラを削除します。

$('.confirm-box .yes-button').click(function() { 
    callback(); 
}); 

あなたは.yes-button要素にイベントハンドラをバインドしている:あなたがコードを実行

+0

これは正解です。私はおそらくそれを正しいものとして受け入れます。 Strynerがコメントを持っているのを待っているのは、予想どおりに動いた場合、代わりに彼の答えを受け入れるからです。 –

1

あなたはクラスによってアイデンティティを設定することによってそれを行うことができ、

var button = $('.confirm-box .yes-button'); 

$('#button1').click(function() { 
    button.removeClass("b").addClass("a"); 
}); 

$('#button2').click(function() { 
    button.removeClass("a").addClass("b"); 
}); 

button.click(function() { 
    if($(this).hasClass("a")){ 
    callBackForButton1(); 
    } else { 
    callBackForButton2(); 
    } 
}); 

単一の要素のイベントハンドラを積み重ねるのは悪い習慣です。

+0

'function(){($(this).hasClass(" a ")?callBackForButton1:callBackForButton2)();を書くことで、JavaScript関数の一次性を強調することができます。 } 'if-elseの代わりに。 –

+0

あなたの答えは正しいですが、私はこれを避けたいと思います。私はカスタムの確認ボックスのために必要なので、あなたのコードでは、私は私のウェブサイト上にある各確認のためのケースとswitch文を書く必要があります。 –

2

。このコードを2回実行すると、2つのイベントがバインドされます。等々。 2つの確認ボックス開いて、同時に、または場合がある場合はもちろんの

$('.confirm-box .yes-button').one("click", function() { 
    callback(); 
}); 

これは問題があります。イベントハンドラは、それが発射された最初の時間の後に除去されるように

一つの解決策は、代わりに.oneを使用することです2つの.yes-button要素がありますが、単純なユースケースではうまく動作します。

+0

私は本当にこれが答えになることを期待していましたが、それを書くのに最も直感的な方法だと思われましたが、残念ながらそれはうまくいきません。それでもそれらのコールバック関数はスタックされます。 .oneはイベントが実行された後にボタンからアンバインドされるため、そのコードが決して実行されず、イベントのバインドが解除されることはありません。そのコールバックをスタックするだけです機能。 –

+0

@MarioPlantosar私はそれを考慮していませんでした。彼らがキャンセルを押すと、このメソッドは間違いなく動作しません。イベントのバインドを解除する方法があります。また、[イベント名前空間](https://api.jquery.com/event.namespace/)を使用して、要素の他のクリックイベントを誤ってバインドしないようにすることをお勧めします。 – Stryner

1

何が起こっているかは、ボタンをクリックするたびにcallFunctionメソッドが実行されていることです。このコードブロックを実行し、$( '。confirm-box .yes-button')ボタンにイベントリスナーを適用します。ボタンをN回クリックするとクリックリスナーもN回適用されます。 1つの解決策は、関数を変数に格納することです。

最終目標は何かわかりませんが、これが1つの解決策です。 別の解決策は、毎回ボタンのイベントリスナーを削除することです。

var functionToCallOnYes = function() {}; 

$('#button1').click(function() { 
    functionToCallOnYes = function() { 
    alert("test"); 
    }; 

}); 

$('#button2').click(function() { 
    functionToCallOnYes = function() { 
    alert("test2"); 
    }; 
}); 


$('.confirm-box .yes-button').click(function() { 
    console.log(functionToCallOnYes); 
    functionToCallOnYes(); 
}); 
+0

これは私が提案しようとしていた解決策でしたが、すべての方法が妥当です。 – Barmar

+0

@Barmar私は同意します!自分自身で新しいことを学びました。私はOPが一度だけ実行するために同じイベントを複数回バインドすることが、ほとんどの場合、最良の解決策ではないことを理解してくれることを願っています。 –

+0

あなたの答えは絶対に正しいですが、私の使用例では実際に行く方法ではありません。私はカスタムの確認ボックスのために必要なので、コールバック関数をパラメータとして渡すことができます。そうすれば、私は確認のようなものを書くことができます( "あなたは本当にそれをしたいですか?"、function(){{//確認された場合は何か})。 –

0

はい、余分なコールバックが積み重なっています。 $('button1').click(f)では、button1をクリックするたびにパラメータなしで関数fが呼び出されます。この場合、fcallFunctionです - 呼び出されるたびに新しいハンドラを任意の.confirm-box .yes-button要素にアタッチする関数です。したがって、N回目のクリックでは、N-1アラートが必要です。

このようにするには、JavaScriptで関数を名前で参照できます。したがって、function test() { console.log("test"); };がある場合は$(".confirm-box").click(test)を1回だけ書くことができ、.confirm-boxをクリックするたびにtestがコンソールに表示されます。

通常、コールバックをコールすることを目的とするコールバックがある場合は、そのコールバックを削除できます。