开发者问题收集

将迭代器索引放入 onmousedown 函数中

2013-11-13
117

我正在尝试做一件看似微不足道的事情,但我搞不清楚。我正在迭代 document.getElementByClassName 方法找到的项目。我使用索引来执行此操作,以便可以跟踪某些内容,并且我需要该特定元素的 onmousedown 事件中的索引,但是我不知道该怎么做。

var items = document.getElementsByClassName("someClass");

    for (var i = items.length - 1; i >= 0; i--)
    {
        items[i].onmousedown=function(){
            //This does not work:
            var index = i; //I need the i variable from the loop above in here.
            console.log(index);
            this.innerHTML = doSomeWorkWith(index);
        };  

    }

有人知道怎么做吗?我曾考虑过将其添加到元素本身,以便可以在那里访问变量,但我宁愿不这样做,因为它会使 html 代码变得混乱。

3个回答

您需要将索引保持在闭包中,例如

for (var i = items.length - 1; i >= 0; i--){
    (function(index){
        ...do anithing
    })(i); 
}
Igor Benikov
2013-11-13

您需要使用另一个函数动态创建处理程序函数。这可以通过使用立即调用函数表达式 (IIFE) 轻松完成。这样,您将在定义处理程序时而不是在执行处理程序时对 i 进行求值。

var items = document.getElementsByClassName("someClass");
for (var i = items.length - 1; i >= 0; i--) {
    items[i].onmousedown = (function (index) {
        return function () {
            console.log(index);
            this.innerHTML = doSomeWorkWith(index);
        }
    })(i);
}

基本上,我没有直接将函数分配给 onmousedown ,而是动态创建一个具有 i 硬编码值的函数。
为了创建该处理程序函数,我使用了另一个函数,我在定义它之后立即(就地)调用它,而无需分配名称。(当然,我可以在全局范围内创建该函数并在此处使用它,但由于我不需要它在其他任何地方,我为什么要这样做?)

[编辑]:要在该函数内使用该事件,请使用

var items = document.getElementsByClassName("someClass");
for (var i = items.length - 1; i >= 0; i--) {
    items[i].onmousedown = (function (index) {
        return function (event) {
            this.innerHTML = doSomeWorkWith(index);
            // do something with "event" here
        }
    })(i);
}
Johannes H.
2013-11-13

这是一个经典问题,匿名函数捕获变量而不是其值,因此当确实调用它时,当前值并不正确。

有关更多信息,请参阅此链接: JavaScript 匿名函数的参数

Jérémy Dutheil
2013-11-13