2016-05-17 9 views
0

以下のボタンは、クリックするとコンソールに数値を出力します。 Fire 1は1を出力し、Fire 2は出力2を出力します。forループ内のjQueryクリック関数にカウンタを渡す

私はループを使用してfire(n)を呼び出す関数に1-4を渡していますが、ボタンのどれかをクリックしても出力が得られません。私はthis questionの答えに従ってみましたが、それは私のために働いていません。

私がforループの代わりにコメントアウトしたコードを使用すると、すべて正常に動作します。 forループを使用すると、これはなぜ機能しませんか?

function fire(n) { 
 
    console.log(n); 
 
} 
 

 
for (var i = 1; i <= 4; ++i) { 
 
    $("#fire" + i).on("click", fire(i)); 
 
} 
 

 
/* 
 
$("#fire" + 1).on("click", function(){fire(1)}); 
 
$("#fire" + 2).on("click", function(){fire(2)}); 
 
$("#fire" + 3).on("click", function(){fire(3)}); 
 
$("#fire" + 4).on("click", function(){fire(4)}); 
 
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="fire1">Fire 1</button> 
 
<button id="fire2">Fire 2</button> 
 
<button id="fire3">Fire 3</button> 
 
<button id="fire4">Fire 4</button>

+1

';'あなたはfire' [JavaScriptのクロージャは、内部ループのコールバック –

+0

可能性のある重複したとして、それを設定していない '呼んでいる - シンプルな実用的な例](http://stackoverflow.com/questions/750486/javascript-closure-inside-loop-simple-practical-example) –

+0

この例では 'for'を使用する必要はありません –

答えて

3

あなたは、クリックハンドラに機能を渡す必要があります。あなたはundefinedを渡しています。これは、fire(i)が関数を実行しているため、戻り値の値-をハンドラとして設定しているためです。

新しい関数を各反復ごとに生成する必要があります。クロージャーは、それぞれi値を「キャプチャ」します。

function fire(n) { 
    return function(){ 
     console.log(n); 
    } 
} 

for (var i = 1; i <= 4; ++i) { 
    $("#fire" + i).on("click", fire(i)); 
} 

fire()機能が何かを返すがいかに今注意してください。それは関数を返す。各クリックハンドラごとに異なるもので、各反復のi値を「取得」します。

+1

どのようにu型が速くなりますか? –

+1

@Austin:Magic! :-D –

+0

閉鎖として知られているものではありませんか? – user1958756

3

$("#fire" + i).on("click", fire(i));を実行しているときは、実際にはfire関数を呼び出しています。あなたがしたいのは、メソッドのパラメータをバインドすることです。

これを行う簡単な方法の1つは、正しい値を持つ新しい関数を返す関数を作成してリスナーに追加することです。

function fire(n) { 
    return function() { 
     console.log(n); 
    } 
} 

もう一つの方法はあなたのためにこれを行いbindを、使用することができます。

for (var i = 1; i <= 4; ++i) { 
    $("#fire" + i).on("click", fire.bind(this, i)); 
} 

のようなものは、最初のパラメータは、関数を呼び出すときにthisに使用するものですし、次のパラメータは、元の関数へのパラメータです。

0

各ボタンIDには、ループで抽出して使用する情報があるため、次の回避策を提案します。

( "クリック"、火(I))の

function fire(n) { 
 
    console.log(n); 
 
} 
 

 
$('button[id^=fire]').on('click',function() { 
 
fire(this.id.split("fire")[1]); 
 
}); 
 

 
/* 
 
$("#fire" + 1).on("click", function(){fire(1)}); 
 
$("#fire" + 2).on("click", function(){fire(2)}); 
 
$("#fire" + 3).on("click", function(){fire(3)}); 
 
$("#fire" + 4).on("click", function(){fire(4)}); 
 
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="fire1">Fire 1</button> 
 
<button id="fire2">Fire 2</button> 
 
<button id="fire3">Fire 3</button> 
 
<button id="fire4">Fire 4</button>

関連する問題