2011-10-18 32 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的范围相同(您也应该通过谷歌变量提升以获取更多关于此的信息)。

相关问题