为什么我的 jQuery 事件在循环时没有正确绑定?

发布于 2024-12-10 21:11:16 字数 348 浏览 3 评论 0原文

我正在使用 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”),而不绑定到其他事件。有更好的方法吗?多谢。

I am using the jQuery hotkeys plugin to bind some keypresses to events. I tried to change this to bind looping over an array instead, but it's not working.

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

This code binds all events to the last letter in the array ("c") and none to others. Is there a better way of doing this ? Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

死开点丶别碍眼 2024-12-17 21:11:16

因为 JavaScript 使用函数变量作用域

您希望将 letter 范围限制在其自己的函数中:

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

您的函数基本上是 臭名昭著的循环问题

另请参阅闭包


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

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

Because JavaScript uses functional variable scoping.

You want to scope letter in its own function:

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

Yours is basically a minor variation on the Infamous Loop Problem.

See also closures.


Based on your comments (some of which have been deleted?) I suggest the following approach:

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();
      }
});

The jQuery keydown event executes for every key which the user presses down on - that second argument you're passing to bind doesn't constrain it to only one key.

歌枕肩 2024-12-17 21:11:16

在这种情况下,函数体很重要。如果您在函数表达式中引用任何局部变量(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 = letter[x]; 确实像这样工作,因为 JavaScript 不支持块级作用域,仅功能级别。这意味着在您的代码中,letterletters 处于相同的范围(您还应该谷歌变量提升以获取有关此的更多信息)。

In this case, the body of the function is important. If you are referencing any of your local variables (x, letters, letter, ...) in the function expressions, they "close over" (google closures for more info) the variables and, when the function expression is called to handle the events, they will have a reference to the last value assigned to letter. For example:


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

There are a couple of ways to solve this. One method is to use a self-executing function:

var x = "Alice";

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

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

Your code, var letter = letters[x]; does not work like this because JavaScript does not support block level scoping, only function level. This means in your code, letter is in the same scope as letters (You should also google variable hoisting for more information about this).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文