Переменная продолжает изменяться после назначения функции обработчику события - PullRequest
1 голос
/ 31 октября 2010

У меня есть группа элементов на странице, все идентификаторы которых хранятся в массиве с именем ids [] .

Я инициализировал сторонний DOM-скрипт для каждого из этих элементов div, который определяет, когда элемент был перетащен. Следующим шагом является назначение функции событию onDrag каждого элемента.

Для простоты я просто хотел бы показать всплывающее диалоговое окно, в котором указан идентификатор перетаскиваемого элемента. Я перебираю свой массив следующим образом:

for (i=0;i<ids.length;i++)
{
document.getElementById(ids[i]).onDrag = function(){alert(ids[i])}
}

Все это выглядит хорошо, но переключение события перетаскивания любого из моих элементов вызывает всплывающее диалоговое окно, в котором указан идентификатор последнего элемента в массиве. Другими словами, похоже, что вышеуказанная функция в моей итерации всегда вычисляется для последнего индекса в моем массиве. Я чувствую, что упускаю что-то очень простое здесь, но эта проблема сводит меня с ума.

Ответы [ 2 ]

4 голосов
/ 31 октября 2010

То, с чем вы столкнулись, называется закрытие , и оно является неотъемлемой частью Javascript.

закрытие - это выражение (обычнофункция), которая может иметь свободные переменные вместе со средой, которая связывает эти переменные (которая «закрывает» выражение).

В результате анонимная функция, назначенная ondrag, закрывается в своей среде, включаяпеременная i.Как следствие, всякий раз, когда i изменяется вне этой функции, i будет соответственно содержать новое значение внутри.

Способ, которым вы можете обойти это поведение в текущем контексте, состоит в том, чтобы создать другую область с дополнительным я-excuting функция.

for (var i=0; i<ids.length; i++) {
  document.getElementById(ids[i]).onDrag = (function(i){  // <- i is a parameter
    return function() {
      alert(ids[i]);  // <- i will be the inner value saved from outside
    };
  })(i);  // <- invoke immidiately with the i from outside
}

Вы можете прочитать больше на тему: Использование сценариев для замыканий JavaScript от @ kangax

1 голос
/ 31 октября 2010

Выполните следующие изменения,

for (...){
    SetOnDrag(ids[i]);
}

function SetOnDrag(id)
{
    document.getElementById(id).onDrag = function() { alert(id); };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...