0

我试图将一个变量放入一个循环内运行的 addListener 函数中,但它总是只注意到循环变量的最后一个实例。

例如

for(var i=0; i < data.length; i++) {
    points[i] = new google.maps.LatLng(parseFloat(data[i].lat), parseFloat(data[i].lng));
    gmarkers[i] = new google.maps.Marker({
        map: map,
        position: points[i],
        title: locationdata[i].title
    });
    gmarkers[i].setMap(map);
    bubbles[i] = new google.maps.InfoWindow({
        content: locationdata[i].summary
    });
    google.maps.event.addListener(gmarkers[i], 'click', function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    });
}

所以问题是在底部附近,alert(i) 始终是 data.length 的最后一项,这是有道理的,但我不知道如何纠正这个问题。


Rocket 回答了这个问题并且是正确的,但是语法略有偏差,所以在这里发布真正的语法是为了以后遇到这个问题的任何人:

google.maps.event.addListener(gmarkers[i], 'click', (function(i) {
    return function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    }})
(i));
4

3 回答 3

1

这是 JavaScript 中的一个经典问题。您需要为每个听众做一个闭包。

google.maps.event.addListener(gmarkers[i], 'click', (function(i) {
    return function(){
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    };
})(i));
于 2012-04-19T15:56:19.753 回答
0

Frame.js旨在解决的另一个问题。这是使用 Frame 的更具可读性和可扩展性的解决方案:

for(var i=0; i < data.length; i++) {
    Frame(function(next, i){
        google.maps.event.addListener(gmarkers[i], 'click', function() {
            alert(i);
        });
        next();
    }, i);
}
Frame.init();
于 2012-04-19T16:17:42.683 回答
0

另一种方法是将您的 addListener 函数放在另一个函数中,并在循环中调用它。正如 Rocket 在他的回答中所说,这是一个关闭的问题,如果你不理解它可能是一个大问题。我不是说我这样做,但我已经尝试了几件事,当你使用这样的单独方法时,我更喜欢它:

function addEventListener(i){
    google.maps.event.addListener(gmarkers[i], 'click', function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    });
}

但这只是个人喜好问题。只是想我也会加入另一个选项:)

于 2012-04-19T18:43:54.787 回答