我正在编写一个简单的JavaScript表单,它是一个设备列表,每个设备旁边都有一个按钮,按钮应该将您带到文本字段,您可以在其中编辑有关设备的信息。相反,所有按钮都会将您带到列表中最后一个设备的信息。以下是我正在创建列表的片段:
for(var i in portal.clients){
var row = document.createElement('tr');
var cell2 = document.createElement('td');
var button = document.createElement('button')
var title = document.createTextNode("Edit Config")
button.appendChild(title)
button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
cell2.appendChild(button)
row.appendChild(button)
var cell1 = document.createElement('td');
var client = document.createTextNode(portal.clients[i].info.description.name)
cell1.appendChild(client)
row.appendChild(cell1)
table.appendChild(row);
}
我认为问题在于,当单击按钮时,i
函数声明中的onClick
将被评估,而不是像我指的那样声明函数。有没有办法可以在声明函数时强制求变量?或者我是否应该使用其他方法将客户端索引传递给函数?
答案 0 :(得分:4)
任何时候你想在回调中使用你的迭代变量i
(即在你的循环完成之后才会被评估的东西)你需要在新范围内捕获变量。
for(var i in portal.clients){
(function(i){
// do something later with i
})(i);
}
关于JavaScript中的作用域,这里有很多关于SO的讨论。我强烈建议您阅读它,因为以任何重要方式理解JavaScript都是必不可少的。
答案 1 :(得分:1)
您需要创建一个新范围,其中i
的副本适用于每次迭代。在您提供的代码中,您可以通过编写一个立即运行的函数来创建一个新的作用域,并返回您希望与附加的新作用域中的变量一起使用的实际函数:
for(var i in portal.clients) {
var row = document.createElement('tr');
var cell2 = document.createElement('td');
var button = document.createElement('button')
var title = document.createTextNode("Edit Config")
button.appendChild(title)
button.onclick = (function(i){return function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}; })(i);
cell2.appendChild(button)
row.appendChild(button)
var cell1 = document.createElement('td');
var client = document.createTextNode(portal.clients[i].info.description.name)
cell1.appendChild(client)
row.appendChild(cell1)
table.appendChild(row);
}
答案 2 :(得分:0)
您可以通过将循环置于自执行功能中来解决它。未经测试的例子:
for(var i in portal.clients){
(function (i) {
var row = document.createElement('tr');
var cell2 = document.createElement('td');
var button = document.createElement('button')
var title = document.createTextNode("Edit Config")
button.appendChild(title)
button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
cell2.appendChild(button)
row.appendChild(button)
var cell1 = document.createElement('td');
var client = document.createTextNode(portal.clients[i].info.description.name)
cell1.appendChild(client)
row.appendChild(cell1)
table.appendChild(row);
})(i);
}