我知道这个问题有很多问题,但我仍然无法找到使这项工作正常工作的方法。
代码:
function doStuff () {
for (var i = 0; i< elementsList.length; i++) {
elementsList[i].previousSibling.lastChild.addEventListener("click", function(){
toggle(elementsList[i])}, false);
}
} // ends function
function toggle (element) {
alert (element);
}
问题在于将变量传递给toggle函数。它与this关键字一起使用(但是它会发送对被点击项目的引用,在这种情况下是无用的),但不会与在Firefox中警告为未定义的elementsList [i]一起使用。
据我所知,使用匿名函数调用函数足以解决闭包问题,所以我错过了什么?
答案 0 :(得分:3)
尝试:
function startOfFunction() {
for (var i = 0; i< elementsList.length; i++) {
elementsList[i].previousSibling.lastChild.addEventListener(
"click",
(function(el){return function(){toggle(el);};})(elementsList[i]),
false
);
}
} // ends function
function toggle (element) {
alert (element);
}
答案 1 :(得分:1)
问题是,你想使用var i
! onClick事件中提供了i
(自封闭和填充后)。由于你有一个循环,i
被计算在内。现在,如果您点击任何元素,i
将始终为elementsList.length
(因为所有事件函数都访问相同的i
)!
使用Matt的解决方案将起作用。
答案 2 :(得分:1)
作为解释:您在for循环中使用的匿名函数引用变量“i”以使元素切换。由于匿名函数使用变量的“实时”值,当有人点击元素时,“i”将始终为elementsList.length + 1.
Matt的代码示例通过将i粘贴到另一个“固定”的函数中来解决这个问题。这总是成立:
如果迭代连接事件的元素,不要使用简单的匿名函数,而是为每个元素创建一个新函数。 Matts答案的可读性更高的版本是:
function iterate () {
for (var i = 0; i < list.length; i++) {
// In here, i changes, so list[i] changes all the time, too. Pass it on!
list[i].addEventListener(createEventFunction(list[i]);
}
}
function createEventFunction (item) {
// In here, item is fixed as it is passed as a function parameter.
return function (event) {
alert(item);
};
}
答案 3 :(得分:0)
尝试:
function doStuff () {
for (var i = 0; i< elementsList.length; i++) {
(function(x) {
elementsList[x].previousSibling.lastChild.addEventListener("click", function(){
toggle(elementsList[x])}, false);
})(i);
}
} // ends function
我认为传递elementsList[i]
可能是一个问题,所以上面的代码有一个应该有用的闭包。