我的所有标记都有一个共享infoWindow
。如果我使用jquery的$().each(function(){})
,它会很好用,但是如果我将它更改为JavaScrips的native或while循环,它就不会按预期工作。
每当我点击一个标记时,它都会打开最后一个填充标记的infoWindow
,而不是点击的标记infoWindow
。
这有效:
$(stores).each(function() {
var storeId = $(this).attr('storeId');
var address = $(this).attr('rawAddress');
var city = $(this).attr('city');
var state = $(this).attr('state');
var zip = $(this).attr('zip');
var lat = $(this).attr('lat');
var lng = $(this).attr('lng');
var distance = $(this).attr('distance');
//create marker
var point = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({ position: point
, map: InStorePickup.map
, title: city + ' #' + storeId
});
//create infowindow content
var infoWindowContent = '<div style="font-size: 8pt;">'
+ '<strong>' + city + ' #' + storeId + '</strong> (' + parseFloat(distance).toFixed(2) + 'mi)<br />'
+ address + '<br />' + city + ', ' + state + ' ' + zip
+ '</div>';
google.maps.event.addListener(marker, 'click', function() {
InStorePickup.openInfoWindow(marker, infoWindowContent);
});
bounds.extend(point);
});
但这不起作用:
for (var i = 0; i < 3; i++) {
var store = stores[i];
var storeId = $(store).attr('storeId');
var address = $(store).attr('rawAddress');
var city = $(store).attr('city');
var state = $(store).attr('state');
var zip = $(store).attr('zip');
var lat = $(store).attr('lat');
var lng = $(store).attr('lng');
var distance = $(this).attr('distance');
//create marker
var point = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({ position: point
, map: InStorePickup.map
, title: city + ' #' + storeId
});
//create infowindow content
var infoWindowContent = '<div style="font-size: 8pt;">'
+ '<strong>' + city + ' #' + storeId + '</strong> (' + parseFloat(distance).toFixed(2) + 'mi)<br />'
+ address + '<br />' + city + ', ' + state + ' ' + zip
+ '</div>';
google.maps.event.addListener(marker, 'click', function() {
InStorePickup.openInfoWindow(marker, infoWindowContent);
});
bounds.extend(point);
}
有什么想法吗?
答案 0 :(得分:4)
您将在for
循环中拥有a very common closure problem。顺便提一句I have answered a similar question就这个话题就在昨天,您可能想要查看。
封闭在闭包中的变量共享相同的单一环境,因此在调用click
回调时,循环将运行,infoWindowContent
变量将指向最后一个分配给它的价值。
解决这个问题的一种方法是使用函数工厂进行更多闭包:
function makeInfoWindowListener (pMarker, pContent) {
return function() {
InStorePickup.openInfoWindow(pMarker, pContent);
};
}
// ...
for (var i = 0; i < 3; i++) {
// ...
var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';
google.maps.event.addListener(
marker,
'click',
makeInfoWindowListener(marker, infoWindowContent)
);
}
如果你不熟悉闭包的工作方式,这可能是一个非常棘手的话题。您可能有兴趣查看以下文章以获得简要介绍:
<强>更新强>
jQuery示例的工作原因是因为传递给each()
方法的函数将每个迭代都包含在自己的范围内。您可以在普通的JavaScript示例中实际执行相同的操作:
for (var i = 0; i < 3; i++) {
// each iteration will now have its own scope
(function () {
var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';
google.maps.event.addListener(marker, 'click', function() {
InStorePickup.openInfoWindow(marker, infoWindowContent);
});
})();
}
第二次更新:
请注意,第一个示例也可以使用匿名函数重写如下:
for (var i = 0; i < 3; i++) {
// ...
var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';
google.maps.event.addListener(marker, 'click', (function (pMarker, pContent) {
return function() {
InStorePickup.openInfoWindow(pMarker, pContent);
};
})(marker, infoWindowContent));
}