2

我有一个这样的javascript代码,这总是给我一个问题

    for(var i=1;i<9;i++){
        document.getElementById('element'+i).onclick=function(){
             theFunc(i)
        }
    }

它选择正确的元素并添加 onclick。但是,当我输入控制台时, document.getElementById('element1").onclick它会返回theFunc(i)(not theFunc(1))

所以无论点击哪个元素,它都会调用theFunc(9)(最后 i 是 9)

我的代码有什么问题?

4

3 回答 3

5

正如您所发现的,您的事件处理函数具有对 的持久引用i而不是其值的副本。

为了防止这种情况,让函数关闭其他不会改变的东西:

for(var i=1;i<9;i++){
    document.getElementById('element'+i).onclick=makeHandler(i);
}

function makeHandler(index) {
    return function() {
        theFunc(index);
    };
}

makeHandler创建一个关闭 的函数index,它是 的的副本i,因此不会随着循环的继续而改变。每个事件处理程序都有自己的 index.

也就是说,创建一堆实际上相同的事件处理函数通常意味着您可以重新设计一点并只使用一个处理函数。例如,在这种情况下,您可以这样做:

for(var i=1;i<9;i++){
    document.getElementById('element'+i).onclick=theHandler;
}

function theHandler() {
    func(parseInt(this.id.replace(/\D/g, ''));
}

id...它从元素中获取要使用的值。

另一种方法是委托,您实际上将click事件挂钩到祖先元素(所有这些 elementX 的共同点),然后当点击发生时,查看event.target它的祖先以了解您应该做什么。

于 2013-08-06T14:36:20.280 回答
1

TJ Crowder 的回答是解决您的问题的最佳方法。您在闭包中遇到的这个“问题”是多种语言的设计,被称为范围。

这里很好地解释了 JavaScript 中的不同作用域(包括闭包)以及如何使用它们。 http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

于 2013-08-06T14:42:44.490 回答
0

当你说theFunc(i)你正在创建一个围绕 的闭包时i,这样每个函数调用都会引用同一个变量。您需要将函数包装在外部闭包中,以确保每个函数调用都使用唯一的变量:

for(var i=1;i<9;i++){
  (function(i){

    document.getElementById('element'+i).onclick=function(){
         theFunc(i);
    }

  })(i);
}
于 2013-08-06T14:36:35.907 回答