【问题标题】:Why are my jQuery events not binding properly when in a loop?为什么我的 jQuery 事件在循环中没有正确绑定?
【发布时间】:2011-12-10 08:16:05
【问题描述】:

我正在使用 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”),而没有绑定到其他字母。有没有更好的方法来做到这一点?非常感谢。

【问题讨论】:

  • 为什么有人要绑定所有这些事件监听器?那是一些可怕的表现。哎呀。
  • 要么使用 switch 语句,要么使用包含所有功能的对象。为 keyup 添加一个事件处理程序,为 keydown 添加一个事件处理程序。在对象中查找函数或让其与 switch case 一起找到。

标签: javascript events jquery hotkeys


【解决方案1】:

因为 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


根据您的 cmets(其中一些已被删除?)我建议以下方法:

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 keydown 事件针对用户按下的每个键执行 - 您传递给 bind 的第二个参数不会将其限制为只有一个键。

【讨论】:

  • 感谢您的帮助。它现在只使用一个事件侦听器;)
【解决方案2】:

在这种情况下,函数的主体很重要。如果您在函数表达式中引用任何局部变量(xlettersletter、...),它们会“关闭”(谷歌关闭以获取更多信息)变量,并且当函数调用表达式来处理事件,它们将引用分配给字母的最后一个值。例如:


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 处于同一范围内(您还应该谷歌变量提升以获取更多信息)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多