12

如何在i下面的 for 循环中保持对变量的访问?我正在努力学习,而不仅仅是得到答案,所以一些解释会非常有帮助。谢谢!

var el, 
    len = statesPolyStrings.length;

for (var i = 0; i < len; i++) {
    el = document.getElementById(statesPolyStrings[i]);

    google.maps.event.addDomListener(el, 'mouseover', function() {
        $("#"+statesPolyStrings[i]).addClass("highlight");
        statesPolyObjects[i].setOptions({ strokeWeight: '2' });
    });
}
4

3 回答 3

29

您的所有回调共享相同的i变量。
当事件处理程序实际运行时,i是在数组末尾之后。

您需要将循环体包装在一个以参数为参数的自调用函数中i
这样,每次迭代都会得到自己的、不变的i变量。

例如:

for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i) {
        ...
    })(i);
}
于 2012-06-08T18:23:02.463 回答
2

自调用函数的技巧很有效:它创建了一个新的范围(可能是 google 的“函数 javascript 中的范围”),因此i作为不同的变量处理,并将正确的值传递给您的事件侦听器回调函数。

但是您实际上不需要使用 jQuery再次找到您的元素,因为您已经为它分配了一个事件侦听器,并且在您的函数内部您可以使用this.

无论如何,当您使用 jQuery 时,通过传递元素的 id 和数组(假设您正在处理唯一的 ID)很容易找到正确的索引(您的)。如果没有,i也会失败,因为它取它找到的第一个)。statesPolyObjects$.inArray()statesPolyStrings$("#"+statesPolyStrings[i])

var el;

for (var i = 0, len = statesPolyStrings.length; i < len; i++) {
    el = document.getElementById(statesPolyStrings[i]);

    google.maps.event.addDomListener(el, 'mouseover', function(event) {
        $(this).addClass("highlight");
        statesPolyObjects[$.inArray(this.id, statesPolyStrings)].
            setOptions({ strokeWeight: '2' });
    });
}

如果您仍然想坚持使用自调用功能,则无论如何都应该更改以下行:

("#"+statesPolyStrings[i]).addClass("highlight");

$(this).addClass("highlight");

如果您对事件不够熟悉,this您可能想阅读这篇文章: http ://www.sitepoint.com/javascript-this-event-handlers/

您可能已经注意到我还在event匿名回调函数中编写了参数。尝试console.log使用任何事件侦听器回调函数免费提供此事件,并探索您可以访问的所有其他内容。例如,您可以找到您单击的实际元素event.target(因为实际的鼠标悬停可能发生在您元素的子元素上)。所以:

google.maps.event.addDomListener(el, 'mouseover', function(event) {
    console.log(event);
    ...

并打开浏览器的控制台以查看传递的事件...

请注意,尽管这google.maps.event.addDomListener会传递一些不同的东西document.body.addEventListener,并且浏览器之间也存在差异。例如,jQuery.on() 在事件对象中也提供了一些不同的东西,但你至少可以在所有浏览器中依靠相同的数据。

于 2013-09-08T11:19:02.837 回答
1
for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i){
        google.maps.event.addDomListener(document.getElementById(statesPolyStrings[i]), 'mouseover', function() {
        $("#"+statesPolyStrings[i]).addClass("highlight");
        statesPolyObjects[i].setOptions({ strokeWeight: '2' });
        });
    })(i)
}
于 2012-06-08T18:24:03.433 回答