我正在构建一个按钮列表,我希望每个按钮都能触发 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);
}
}
感谢。
答案 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);
}
答案 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
。
只有在闭括号声明周围放置外括号时才会发生自动调用。