2011-12-24 4 views
3

私は、次のようなループ内でイベントハンドラをバインドしようとしている:のみ(値「4」)バインドされ、最後の1を保持しループ内でイベントハンドラをバインドするにはクロージャが必要ですか?

 var tabs = ['one', 'two', 'three', 'four'] 

     for(var i = 0; i < tabs.length; i++) { 
      alert(tabs[i]); 
      var id = i; 
      $('#' + tabs[i]).bind('click', function() { 
       loadTabs(id, tabs); 
      }); 
     } 

私は現在、仕事をして、このコードを統合しようとしている:

 $('#one').click(function() { 
      loadTabs(0, tabs); 
     }); 

     $('#two').click(function() { 
      loadTabs(1, tabs); 
     }); 

     $('#three').click(function() { 
      loadTabs(2, tabs); 
     }); 

     $('#four').click(function() { 
      loadTabs(3, tabs); 
     }); 

は、私が原因this postに閉鎖を必要とするかもしれないと思いました。

答えて

5

あなたはother postで読んだことについて正しいです。 あなたはそれぞれ単一のonclickハンドラに引数をバインドするために閉鎖を行う必要があります。あなたはまた、curryingに見たいと思うかもしれません

$('#' + tabs[i]).bind(
    'click', 
    (function(id) { 
     return function() 
     { 
      loadTabs(id, tabs); 
     }; 
    })(id) 
); 

。 この例では、最初の引数を渡された関数にバインドし、新しい関数を返す小さなヘルパー関数を作成します。

function curry(func, arg1) 
{ 
    return function() 
    { 
     func(arg); 
    }; 
} 

そして、このように一緒にそれを置く:それは、他の引数を無視するので、私のカレー関数は、カリー化の定義と一致していません

$('#' + tabs[i]).bind(
    'click', 
    curry(function(id) { loadTabs(id); }, id) 
); 

注意を。しかし、それはあなたの場合に有効です。

+0

興味深い。ありがとう! –

1

既にjQueryを使用しているので、jQuery.eachをこのタスクに使用できます。そのため、あなたが正しく仮定したように、あなた自身で行う必要はありません。closures

var tabs = ['one', 'two', 'three', 'four']; 

$.each(tabs, function(idx, tab) { 
    $("#" + tab).on("click", function() { 
     alert(idx); 
     //loadTabs(idx, tabs); 
    }) 
}); 

jsfiddle

+0

これは今、デモのhtmlのdivのID名に警告していますか? –

+0

また、(タブ配列の)特定の順序で追加することを前提としています。ポイントはこれをよりモジュラー化して順序が重要でないようにすることです。 –

+0

@bob_cobb:私の例では、配列内の現在のアイテムのインデックスが警告されます。しかしそれはデバッグのためのものです。 2番目のコメントは理にかなっていません。なぜなら、ループを使って同じことをもっと複雑にするからです。それにもかかわらず、「モジュラー型」とはどういう意味ですか?私はあなたが他の方法で掲示したこの特定の問題を解決するために何らかの状況を考えることができません。 – Andreas

関連する問題