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

Attaching Events in a Loop (IE 7)

本文关键字:IE 事件 循环      更新时间:2023-09-26

我正在尝试将函数绑定到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或绑定方法来执行此操作,但在IE 7中两者都不允许。我什至知道 attachEvent 方法适用于 ie7,但由于我需要传递参数,我需要将函数包装在匿名函数中以使用 attachEvent(至少这似乎是真的),这是原始问题。

关于这个主题有什么不太笨拙的想法吗?谢谢。

使用匿名函数来影子j

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

这将强制在函数范围内按值传递j

您不一定需要为每个绑定事件使用 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 在同一范围内),但这可能会使难以看到循环的实际作用(因为您必须查找一次性函数)。我没有看到任何明显的其他解决方案,因为无论如何您都需要关闭。

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

如果没有您网站的 HTML 代码(以及 showLabel() 和 selectNew() 的确切工作原理),我无法进一步帮助您,但通常,在导航列表上设置单击和鼠标悬停处理程序可以通过这样简单的事情来完成;

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

老实说,在这种情况下,您只需要一个索引,我会将其直接存储在元素上。

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 遍历"解决方案,但这取决于您的标记。