在循环中附加事件(IE 7)

时间:2013-01-29 23:19:00

标签: javascript events for-loop closures anonymous-function

我正在尝试将函数绑定到Internet Explorer 7中节点列表中的项目。

for(var j = 0; j < navLabels.length; j++)
{
    navInsets[j].onmouseover = function(){showLabel(navLabels[j], true);};
    navInsets[j].onmouseout = function(){showLabel(navLabels[j], false);};
    navInsets[j].onclick = function(){selectNew(j);};
    navLabels[j].onclick = function(){selectNew(j);};
}

showLabel()和selectNew()都是我自己的函数。它们每个都需要传递一个索引,在这种情况下,它是j。

我知道,在匿名函数中,j最终会成为对j的引用,而不是j的值。我也知道我可以使用addEventListener或bind方法来执行此操作,但IE 7中都不允许这样做。我甚至知道attachEvent方法适用于ie7,但由于我需要传递参数,我需要换行匿名函数中的函数使用attachEvent(至少看起来是真的),这是原始问题。

关于这个问题的任何不太讨厌的想法?感谢。

4 个答案:

答案 0 :(得分:3)

使用匿名函数隐藏j

(function(j) {
    navInsets[j].onclick = function() {selectNew(j);};
    ...
})(j);

这会强制j通过函数范围内的值传递。

答案 1 :(得分:2)

您不一定需要为每个绑定事件使用IIFE。您可以在所有事件绑定中使用相同的捕获j

for(var j = 0; j < navLabels.length; j++) {
    (function(j) {
        navInsets[j].onmouseover = function(){showLabel(navLabels[j], true);};
        navInsets[j].onmouseout = function(){showLabel(navLabels[j], false);};
        navInsets[j].onclick = function(){selectNew(j);};
        navLabels[j].onclick = function(){selectNew(j);};
    })(j);
}

我认为你不能得到任何“清洁”。您可能能够提取匿名函数并使其成为命名函数(与navInsetsnavLabels在同一范围内),但这可能使得很难看到循环实际执行的操作(因为您必须去查找一次性使用功能)。我没有看到任何明显的其他解决方案,因为无论如何你都需要一个闭包。

答案 2 :(得分:0)

查看您的代码,我认为您可以通过使用事件冒泡/委托来优化您的代码。如果你准备投入一些时间,你可以通过学习jQuery获得很多。

如果没有您网站的HTML代码(以及showLabel()和selectNew()的确切工作方式,我无法帮助您,但通常情况下,在导航列表上设置点击并鼠标悬停在处理程序上可以通过某种方式完成就这么简单;

 $('ul#nav').on('click', 'label', function(){
     selectNew(this);
 });

答案 3 :(得分:0)

说实话,在这样的情况下,你需要的只是一个索引,我会将它直接存储在元素上。

for(var j = 0; j < navLabels.length; j++)
{
    navInsets[j].j = j;
    navInsets[j].onmouseover = function(){showLabel(navLabels[this.j], true);};
    navInsets[j].onmouseout = function(){showLabel(navLabels[this.j], false);};
    navInsets[j].onclick = function(){selectNew(this.j);};
    navLabels[j].onclick = function(){selectNew(this.j);};
}

这是一个非常轻便,干净,快速的解决方案。只是不要存储元素本身,因为这可能会导致泄漏。

但是只存储一个索引是无害的,它避免了闭包泄漏的可能性。


此外,可能有更好的“DOM遍历”解决方案,但这取决于您的标记。