设置onclick以在循环中使用变量的当前值

时间:2011-05-18 17:21:46

标签: javascript variables loops scope

标题可能没有意义,也不会单独描述,所以这里是代码示例:

for(var a=0;a<10;a++) {
    var b=document.createElement('b')
    b.onclick=function() {
        alert(a)
    }
    b.innerHTML=a
    document.body.appendChild(b)
}

奇怪的是,当我将innerHTML设置为a时,它使用a的当前值。因此,此代码创建了10个<b>个元素,其值为0,1,2,3,4,5,6,7,8和0。这完美无缺。然而,onclick功能不是什么。当单击任何这些元素时,它返回a(10)的最终值。我已尝试将另一个变量设置为a,然后在onclick事件中使用该另一个变量,但仍然会返回a的最终值。如果设置了onclick,我将如何使用a的值?

2 个答案:

答案 0 :(得分:28)

尝试以下

b.onclick= function(arg) {
    return function() {
        alert(arg);
    }
}(a);

你遇到的问题是javascript不使用块范围。相反,所有变量都具有其包含函数的生命周期。因此,在所有a函数中只捕获了一个onclick,并且它们都看到了它的最终值。

解决方案通过为每个范围创建新函数和值然后立即将该值设置为当前值a来解决此问题。

这是一个有点扩展且可能更具可读性的版本

var createClickHandler = function(arg) {
  return function() { alert(arg); };
}

for(var a=0;a<10;a++) {
    var b=document.createElement('b')
    b.onclick = createClickHandler(a);
    b.innerHTML=a
    document.body.appendChild(b)
}

答案 1 :(得分:1)

我发现一个肮脏的解决方法是使用创建的对象的 .value 属性来存储我们想要传递给.onclick函数的参数。所以我可以做类似

的事情
for(var a=0;a<10;a++) {
    var b=document.createElement('b')
    b.value=a
    b.onclick=function() {
        myfunc(this.value)
    }
    b.innerHTML=a
    document.body.appendChild(b)
}
function myfunc(n){
  console.log(n)
}

我不确定.value是否适用于每个元素,但它适用于DIV。

编辑:要传递更多值,然后使用某些字符(例如_)连接它们,然后将其拆分

b.value=x+"_"+y+"_"+z

function myfunc(str){
 t=str.split("_")
 x=t[0]
 y=t[1]
 z=t[2]
 console.log(x+","+y+","+z)
}