2011-10-18 30 views
4

我正在使用jQuery hotkeys插件將一些按鍵綁定到事件。我試圖改變這個綁定循環而不是數組,但它不起作用。爲什麼我的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

爲什麼有人會綁定所有這些事件偵聽器?那是一些糟糕的表現。讓人驚訝。 – epascarello

+0

可以使用switch語句或包含所有函數的對象。爲keyup添加一個事件處理程序,爲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的參數不會將其限制爲只有一個鍵。

+0

+1對於臭名昭着的循環問題鏈接 –

+0

對於使用帶有一個事件處理程序的對象+1! – epascarello

+0

感謝您的幫助。它現在只與一個事件監聽器一起工作;) – mikel

1

在這種情況下,函數的主體很重要。如果您在函數表達式中引用了任何本地變量(xletters,letter,...),則它們會「關閉」(google關閉以獲取更多信息)變量,並且在調用函數表達式來處理事件中,他們將參考分配給字母的最後一個值。例如:


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

有幾種方法可以解決這個問題。一種方法是使用一個自動執行功能:

var x = "Alice"; 

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

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

您的代碼,var letter = letters[x];工作是這樣,因爲JavaScript不支持塊級作用域,唯一的功能水平。這意味着在您的代碼中,letterletters的範圍相同(您也應該通過谷歌變量提升以獲取更多關於此的信息)。

相關問題