我发现了一些似乎与此有关的问题,但在我的理解范围内,我的不同,所以这里有。 我已经大大简化了我的代码,甚至用注释替换了一行,但概念是相同的......
function myFunction(options) {
var button;
options.widgets.forEach(function (w) {
button = document.createElement("button");
//add button to the DOM
aListOnMyPage.addEventListener("selectionchanged", function (args) {
var a = button;
});
});
}
因此,对于每个小部件,我创建一个新对象,然后在页面上的列表中添加一个事件侦听器,该函数需要引用我创建的DOM元素(按钮)。 我看到的行为是我的按钮被正确设置在我创建事件监听器的位置,但是当监听器的事件触发时,按钮始终是对我创建的最后一个按钮的引用。 也许这是因为它已经很晚了,但我无法理解为什么会这样做。谁能为我澄清这个?
答案 0 :(得分:3)
当然可以。
这里的问题实际上是范围。我们来看看你写的代码:
function myFunction(options) {
var button;
options.widgets.forEach(function (w) {
button = document.createElement("button"); // UH-OH...
//add button to the DOM
aListOnMyPage.addEventListener("selectionchanged", function (args) {
var a = button;
});
});
}
注意呃哦?您已声明button
应该等于document.createElement("button")
,但由于您未使用var
关键字,因此您已声明了一个全局变量,而不是多个本地变量。这意味着每次循环运行时,侦听器都会引用一个全局变量,这会导致您的问题。
确保在这里使用局部变量,如下所示:
function myFunction(options) {
options.widgets.forEach(function (w) {
var button = document.createElement("button");
//add button to the DOM
aListOnMyPage.addEventListener("selectionchanged", function (args) {
var a = button;
});
});
}
这应该会大大改善你的情况。至少,我希望它能帮助你更进一步。祝你好运。
答案 1 :(得分:1)
我认为你因为闭包而面临这个问题,你myFunction
中使用的按钮变量是相同的,所有更改都是引用更改,所以我认为将变量的声明更改为匿名函数内部应该解决这个问题。
function myFunction(options) {
//var button;
options.widgets.forEach(function (w) {
var button = document.createElement("button");
//add button to the DOM
aListOnMyPage.addEventListener("selectionchanged", function (args) {
var a = button;
});
});
}
此更改在forEach
中为匿名函数提供了单独的button
变量。