Событие JavaScript, использующее отраженное свойство, не возвращает, не может видеть остаток массива - PullRequest
0 голосов
/ 07 сентября 2011

Работая с JavaScript в IE, я использовал свойство отраженное, но проблема в том, что у меня 12 элементов и все предупреждения 12.

Когда я использую setAttribute, проблем нет.

Что у меня так далеко:

    var items = [1,2,3,4,5,6,7,8,9,10,11,12];
    for (i in items)    {
        newdiv = document.createElement("div");

        //newdiv.setAttribute("class","box");
        //newdiv.setAttribute("id",items[i]);
        //newdiv.setAttribute("ondblclick","chkItem("+items[i]+");");

        newdiv.className = "box";
        newdiv.id = items[i];
        newdiv.ondblclick = function() {alert(items[i])}
        newdiv.innerHTML = " " + items[i];
        document.getElementById("items").appendChild(newdiv);
    }

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

изменение:

newdiv.ondblclick = function() {alert(items[i])}

к этому:

newdiv.ondblclick = (function(item) { return function() {alert(item)} })(items[i])

Посмотрите вверх Затворы , и это то, что вас портит в этом случае. Когда вы создаете анонимную функцию, используя function() { }, вы создаете замыкание, которое связано с областью, в которой она была создана. Итак, внутри вашего замыкания ваша переменная i - это та же переменная, которую вы использовали в цикле. Поэтому, когда вы дважды щелкнете по элементу, цикл уже закончен и i == 12. Это было бы так же, как если бы вы поместили alert(i); непосредственно после вашего for(i in items) { } цикла.

Итак, учитывая это, как мой второй пример исправляет это?

Ну, он использует самозапускающуюся анонимную функцию, которая принимает одну переменную, item. Эта функция возвращает замыкание, которое ограничено внутри ее области видимости. Внешнее закрытие немедленно выполняется, передавая items[i], что создает стабильную область видимости для переменной, в которой вы хотите жить.

Замыкания могут быть немного изнурительными, если вы к ним не привыкли, но понимание их - важная часть для получения функционального программирования с использованием JavaScript.

SetAttribute работает, потому что вы создаете новую строку, которая оценивает каждый раз в цикле, вместо поздней ссылки на переменную i.

PS

Вероятно, плохая идея использовать for( in ) {} в массиве. Вы можете получить неожиданные результаты, он должен перебирать все свойства объекта, а не только элементы в массиве. вероятно, безопаснее использовать обычный for(var i=0;i<items.length;i++) {}

0 голосов
/ 07 сентября 2011

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

newdiv.ondblclick = function() {alert(this.id)}

Где this - элемент newdiv.

Пример здесь

...