Добавление событий к элементам внутри цикла - JScript / Closures - PullRequest
1 голос
/ 18 марта 2011

Я создаю список кнопок и хочу, чтобы каждая из них запускала функцию addForm () с текущими members [member] .id .

Но бывает, что только последняя кнопка вызовет событие.

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

Что я делаю не так?

function displayConnections(connections) {
    /*(...)*/

    for (var member in members) {

        connectionsDiv.innerHTML += "<p>" + members[member].firstName + " " + members[member].lastName
        + " ID: " + members[member].id;

        btn = document.createElement("input");
        btn.setAttribute("type","button");
        btn.setAttribute("value","Send Message");
        btn.setAttribute("id",members[member].id);

        btn.onclick = function (id) {
            return function () {
                addForm(id);
            };
        }(members[member].id);

        connectionsDiv.appendChild(btn);

    }     
}

Спасибо.

Ответы [ 4 ]

2 голосов
/ 04 сентября 2011

Ну, вместо тех обходных путей вы также можете использовать:

element.setAtrribute('onClick', 'javascript:functionName(' + parameter + ');');

, который работал для меня и должен работать для вас.

2 голосов
/ 18 марта 2011

Во-первых, помните, что вы не пишете на C # или Java. Структура for (var ... in ...) не выполняет итерацию коллекции. Вы всегда должны проверять hasOwnProperty, чтобы увидеть, относится ли имя свойства к самому объекту:

if (!members.hasOwnProperty(member)) continue;

Затем убедитесь, что значение свойства является объектом, а не функцией и т. Д.

Во-вторых, вашей переменной btn не хватает объявления var. Вы создаете глобальную переменную с именем btn, а не локальную для вашей функции.

Далее, у вас есть ошибка опечатки в вашем исходном коде. Ваш исходный код на самом деле интерпретируется следующим образом (благодаря автоматической вставке точек с запятой в JavaScript функция !):

btn.onclick = function (id) {
    return function () {
        addForm(id);     <-- this id is now the click event's event object, not what you want
    };
};
(members[member].id);   <-- this line will have no side effect

Чтобы запустить вашу программу в оригинальном стиле, вам нужно заключить в скобки определение функции:

btn.onclick = (function (id) {
    return function () {
        addForm(id);
    };
})(members[member].id);
0 голосов
/ 18 марта 2011

В этом блоке кода:

btn.onclick = function (id) {
    return function () {
        addForm(id);
    };
}(members[member].id);

У вас неправильный синтаксис - он должен быть:

btn.onclick = (function(id) {
    return function () {
        addForm(id);
    }
})(members[member].id);

То, что это делает, автоматически вызывает aновое анонимное закрытие, которое имеет локально связанную копию members[member].id в своем параметре id, которое само тогда возвращает закрытие, которое фактически связано с btn.onclick.

.автоматический вызов происходит только в том случае, если вы ставите внешние скобки вокруг объявления закрытия.

0 голосов
/ 18 марта 2011
for (var i = 0; i < 10; i++) {

    // Won't work
    //$('div').eq(i)[0].onclick = function() { alert(i) }; // 10


    $('div').eq(i)[0].onclick = (function(id) {
        return function() {
            alert(id)
        };
    })(i);
}

jsFiddle .

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