2011-10-18 10 views
4

jQueryホットキープラグインを使用して、いくつかのキー押下をイベントにバインドしています。代わりに配列のループをバインドするように変更しようとしましたが、うまくいきません。ループ中にjQueryイベントが正しくバインドされないのはなぜですか?

var letters = ["a","b","c"]; 
for (var x in letters) 
{ 
    var letter = letters[x]; 
    $("el").bind('keydown', letter, function() { /*...*/ }) 
      .bind('keyup', letter, function() { /*...*/ }); 
} 

このコードは、すべてのイベントを配列の最後の文字( "c")にバインドし、他のものはすべてバインドしません。これを行うより良い方法はありますか?どうもありがとう。

+0

誰かがこれらのイベントリスナーをすべてバインドするのはなぜですか?それはそこでいくつかの恐ろしいパフォーマンスです。 Yikes。 – epascarello

+0

switch文またはすべての関数を含むオブジェクトを使用してください。キーアップ用のイベントハンドラとkeydown用のイベントハンドラを追加します。オブジェクト内の関数を検索するか、スイッチケースで見つけてください。 – epascarello

答えて

5

JavaScriptはfunctional variable scopingを使用しているため、

あなたは、独自の機能でスコープletterにしたい:

var letters = ["a","b","c"]; 
letters.forEach(function(letter) { 
    $("el").bind('keydown', letter, function() { /*...*/ } }) 
      .bind('keyup', letter, function() { /*...*/ }); 
}); 

ユアーズは基本的にInfamous Loop Problemのマイナーバリエーションです。

closuresも参照してください。 (削除されたそのうちのいくつかは?)あなたのコメントに基づいて


私は、次のアプローチを提案する:

var events = { 
    a: function() { 
     console.log("a is for ALPHA"); 
    }, 
    b: function() { 
     console.log("b is for BRAVO"); 
    }, 
    c: function() { 
     console.log("c is for CHARLIE"); 
    } 
}; 
jQuery("#el").keydown(function(e) { 
     var ascii = e.keyCode || e.which; 
     var handler = events[String.fromCharCode(ascii).toLowerCase()]; 
     if(handler) { 
      handler(); 
     } 
}); 

jQueryの​​イベントは、ユーザーが上の押下キーごと実行 - その二bindに渡す引数は、それを1つのキーに制限しません。

+0

+1の悪名高いループの問題のリンク –

+0

1つのイベントハンドラでオブジェクトを使用するための+1! – epascarello

+0

ご協力いただきありがとうございます。 1つのイベントリスナーだけで動作しています;) – mikel

1

この場合、関数の本体が重要です。関数式でローカル変数(xlettersletter、...)のいずれかを参照している場合は、変数を「クローズオーバー」(詳細についてはGoogleクロージャを参照)し、変数を処理するために関数式が呼び出されるとイベントには、文字に割り当てられた最後の値を参照します。例:


var x = "Alice"; 
var helloAlice = function() { alert("Hello, " + x); }; 
x = "Bob"; 
helloAlice(); // Alerts "Hello, Bob" 

これを解決する方法がいくつかあります。 JavaScriptはブロックレベルのスコープ、唯一の機能レベルをサポートしていないためvar letter = letters[x];は、このようなない作業を行い、

var x = "Alice"; 

var helloAlice = (function(name) { 
    return function() { alert("Hello, " + name); }; 
})(x); 

x = "Bob"; 
helloAlice(); // Alerts "Hello, Alice" 

あなたのコード:一つの方法は、自己実行機能を使用することです。これは、コード内でletterlettersと同じスコープにあることを意味します(詳細については、Google変数ホイストも参照してください)。

関連する問題