1

我正在尝试动态更改元素的 onClick 事件,我有以下内容:

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; };
}

除了传递给“existingFunction()”的参数是每次调用它时 i=4 的最终值这一事实之外,一切似乎都运行良好。有没有办法将一个函数绑定到 onclick,该函数在绑定时使用 i 的值,而不是它目前正在做的事情,并在 for 循环中引用原始 i。

还有没有一种方法可以执行相同的绑定而不必每次都创建匿名函数?这样我就可以出于性能原因在每个 onclick 中直接引用“existingFunction”?

干杯,勇

4

4 回答 4

4

改变

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; };
}

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = createOneHandler(i);
}

function createOneHandler(number){  
    return function() {  
        existingFunction(number); 
    }  
}

它应该可以正常工作。

工作演示

这里给出了一个很好的解释

JavaScript,是时候了解闭包了

于 2009-11-17T04:16:42.920 回答
1

您发布的代码应该按照您的预期工作,您对 i=4 的问题在其他地方。编辑:这是错误的,rageZ 对范围界定问题是正确的。

关于另一个问题:您所能做的就是减轻冗长

var f = function (i) { return function () { existingFunction(i); return false; } }
for (...) { document.getElementById(...).onclick = f(i); }

顺便说一句,您应该使用 jQuery 之类的东西进行 DOM 操作(简洁的语法),也许还使用 Zeta(http://codex.sigpipe.cz/zeta/)作为函数组合

var f = compose(false_, existingFunction);
for (...) { $(...).click(f(i));
于 2009-11-17T04:17:00.183 回答
1

因为i总是 4,你有一个范围界定问题,我建议你阅读这个。范围界定是非常重要的概念,因此您最好确保了解正在发生的事情。

更好的代码是

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = existingFunction;
}

onclick 将传递一个事件有参数,这样你就可以知道点击了什么元素,即

function existingFunction(event){
  // DO something here
}

你可以在那里阅读更多关于事件的信息。IE 确实具有与其他浏览器完全相同的事件模型,因此您必须处理它。

最后一点,我建议您使用 JS 框架(Jquery、ExtJS、DOJO、Prototype...),因为它会简化您的任务

于 2009-11-17T04:25:16.407 回答
0

万岁!又是闭环!有关更多讨论,参见422784、643542、1552941等。

有没有一种方法可以执行相同的绑定而不必每次都创建匿名函数?

是的,在 ECMAScript 第五版中,您会得到function.bind

for (var i = 1; i < 5; i++)
    document.getElementById('element'+i).onclick= existingFunction.bind(window, i);

与此同时,由于浏览器尚未普遍支持它,您可以对由匿名函数构建的替代实现bind(请参阅此评论的底部)进行猴子补丁作为后备。

或者,为每个元素分配相同的事件处理函数,然后让它查看this.id它是哪个元素编号。

于 2009-11-17T04:58:39.943 回答