0

我有以下代码将onmouseover事件添加到项目符号onload

for (var i = 0; i <= 3; i++) {
    document.getElementById('menu').getElementsByTagName('li')[i].onmouseover = function () { addBarOnHover(i); };
}

这是它正在调用的函数。当鼠标移到菜单项上时,它应该向菜单项添加一个 css 类。

function addBarOnHover(node) {
    document.getElementById('menu').getElementsByTagName('li')[node].className = "current_page_item"; }

调用该函数时,我不断收到错误消息:

"document.getElementById("menu").getElementsByTagName("li")[node] 未定义"

让我难过的是我在addBarOnHover函数中添加了一个 alert(node) 语句来查看参数的值是什么。警报说正在传递的参数的值为 4。我不确定我设置的循环如何发生这种情况。

任何帮助将非常感激。

4

2 回答 2

4

当您关闭迭代变量时,这是一个常见问题。将主体包裹for在一个额外的方法中以捕获迭代变量的值:

for (var i = 0; i <= 3; i++) {
  (function(i){ //here
    document.getElementById('menu').getElementsByTagName('li')[i].onmouseover = function () { addBarOnHover(i); };
  })(i); //here
}

每次进入循环时都会创建一个匿名函数,并将迭代变量的当前值传递给它。i匿名函数内部指的是这个函数的参数,而不是i外部作用域中的。

为了清楚起见,您还可以重命名内部变量:

for(var i=0; i<=3; i++){
  (function(ii){
    //use ii as i
  })(i)
}

在不捕获迭代变量的情况下,i最终在匿名处理程序中使用时的值已经更改为4. 在外部范围内只有一个i,在处理程序的所有实例之间共享。如果您通过匿名函数捕获值,则使用该函数的参数。

于 2012-11-15T03:22:14.403 回答
1

i正在作为引用传递(而不是按值传递),因此一旦onmouseover调用回调, 的值i就已经变为4.

您必须使用另一个函数创建回调函数:

var menu = document.getElementById('menu');
var items = menu.getElementsByTagName('li');

for (var i = 0; i <= 3; i++) {
    items[i].onmouseover = (function(i) {
        return function() {
            addBarOnHover(i);
        };
    })(i);
}

您可以通过创建一个辅助函数使其更具可读性:

var createCallback = function(i) {
    return function() {
        addBarOnHover(i);
    };
};

for (var i = 0; i <= 3; i++) {
    items[i].onmouseover = createCallback(i);
}
于 2012-11-15T03:21:34.040 回答