将事件添加到循环内的元素 - JScript / Closures

时间:2011-03-18 09:54:23

标签: javascript scope closures

我正在构建一个按钮列表,我希望每个按钮都能触发 addForm()函数,并使用当前的成员[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 个答案:

答案 0 :(得分:2)

首先,请记住您不是在编写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);

答案 1 :(得分:2)

嗯,您可以使用以下方法代替这些解决方法:

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

对我有用,也适合你。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

在这段代码中:

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

你的语法错误 - 它应该是:

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

它的作用是自动调用一个新的匿名闭包,它在members[member].id参数中有id的本地绑定副本,然后返回< / em>一个闭包,它实际上绑定到btn.onclick

只有在闭括号声明周围放置外括号时才会发生自动调用。