Почему мои события jQuery не связываются должным образом в цикле? - PullRequest
4 голосов
/ 18 октября 2011

Я использую плагин горячих клавиш 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") и ни к каким другим.Есть ли лучший способ сделать это?Большое спасибо.

Ответы [ 2 ]

5 голосов
/ 18 октября 2011

Поскольку 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 выполняется для каждой клавиши, которую нажимает пользователь - этот второй аргумент, который вы передаете bind, не ограничивает его только одним ключом.

1 голос
/ 18 октября 2011

В этом случае важен текст функции. Если вы ссылаетесь на любую из ваших локальных переменных (x, letters, 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 не поддерживает определение уровня блока, только уровень функции. Это означает, что в вашем коде letter находится в той же области, что и letters (Вы также должны узнать о переменных Google, чтобы узнать больше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...