我目前正在使用以下代码,使用他们的API在Google地图上放置多个标记。
我遇到的问题是多个infowindows无法正常工作(只显示最后一个)。
这里有很多像我这样的问题。实际上,这是一大堆问题: - )
只是一个例子:Trying to bind multiple InfoWindows to multiple Markers on a Google Map and failing
我的问题的解决方案有点简单:只需将点击监听器包含在(匿名)函数中。
然而,我不明白的是为什么我的解决方案不起作用(将数组中的标记和infowindows保存而不是只保存一个变量)。
var markers = [];
var infowindows = [];
// add shops or malls
for (var key in data.markers) {
if (data.markers.hasOwnProperty(key)) {
infowindows[key] = new google.maps.InfoWindow({
content: data.markers[key].infowindow
});
markers[key] = new google.maps.Marker({
position: new google.maps.LatLng(data.markers[key].location.lat, data.markers[key].location.lng),
map: map,
flat: true,
title: data.markers[key].name,
draggable: false
});
var iconFile = 'http://maps.google.com/mapfiles/ms/icons/'+marker_color+'-dot.png';
markers[key].setIcon(iconFile);
google.maps.event.addListener(markers[key], 'click', function() {
infowindows[key].open(map, markers[key]);
});
}
}
所以...我不知道如何得到解决方案如何使用一些函数来封闭监听器(虽然它应该工作,尚未测试它但是会),但我想知道如果我将标记和infowindows添加到数组中,它将无法工作的原因。
答案 0 :(得分:62)
Javascript有一种叫做“闭包”的语言结构。闭包是函数(例如您在上面声明的用于处理单击侦听器的函数(){},它捕获对外部变量的引用。
有很多资源可以比我更好地解释它们,我建议你参考,但这是我最好的尝试:
在此块中:
google.maps.event.addListener(markers[key], 'click', function() {
infowindows[key].open(map, markers[key]);
});
由于“key”已被定义为外部变量,因此该函数将捕获对该变量的引用。所以你期望的地方:
infowindows["helloworld"]
Javascript会将其解释为:
infowindows[reference to key]
当您点击标记时,它会查找“对密钥的引用”以查看密钥的当前值。因为在循环完成之前这可能不会发生,所以key将等于data.markers对象中的最后一个键。并且它将等于您添加的每个点击监听器的值。
正如您所指出的,解决方案是将其包装在一个匿名函数中,以便在添加点击侦听器时让Javascript评估“key”的值。
google.maps.event.addListener(markers[key], 'click', function(innerKey) {
return function() {
infowindows[innerKey].open(map, markers[innerKey]);
}
}(key));
答案 1 :(得分:54)
这对我来说很好!只需向marker对象添加一个新属性,该属性就包含infowindow对象。
var mytext = 'Infowindow contents in HTML'
var myinfowindow = new google.maps.InfoWindow({
content: mytext
});
var marker = new google.maps.Marker({
position: mypos,
map: mymap,
icon: myicon,
title: mytitle,
infowindow: myinfowindow
});
google.maps.event.addListener(marker, 'click', function() {
this.infowindow.open(map, this);
});
答案 2 :(得分:19)
有一种稍微简单的方法可以实现这一目标。您可以为标记添加自定义属性(信息窗口的索引)并在回调函数中引用它。示例如下:
markers = Array();
infoWindows = Array();
for(var i in earthquakes)
{
var location = new google.maps.LatLng(earthquakes[i].geolat, earthquakes[i].geolong);
var marker = new google.maps.Marker({
position : location,
map : map,
animation : google.maps.Animation.DROP,
infoWindowIndex : i //<---Thats the extra attribute
});
var content = "<h3>" + earthquakes[i].title + "<h3>" +
"<a data-ajax='false' target='_blank' href='" + earthquakes[i].link + "'>Link to shakemap.</a>";
var infoWindow = new google.maps.InfoWindow({
content : content
});
google.maps.event.addListener(marker, 'click',
function(event)
{
map.panTo(event.latLng);
map.setZoom(5);
infoWindows[this.infoWindowIndex].open(map, this);
}
);
infoWindows.push(infoWindow);
markers.push(marker);
}
答案 3 :(得分:8)
答案 4 :(得分:2)
function addMarker(Latlng){
marker = new google.maps.Marker({
position: Latlng,
icon:"myicon.jpg",
map: map,
animation: google.maps.Animation.DROP,
title:"My tooltip"
});
//add marker
marker.setMap(map);
contentString = "<h1>Hello World</h1>";
marker.infowindow = new google.maps.InfoWindow({
content: contentString
});
//add click event
google.maps.event.addListener(marker, 'click', function(){
this.infowindow.open(map,this);
});
}
addMarker(some_lat_lang_value);
答案 5 :(得分:1)
我将使用闭包:
(function(infowindow, marker){google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});})(infowindow, marker)
答案 6 :(得分:0)
var infowindow = null;
infowindow = new google.maps.InfoWindow({
content: "loading..."
});
for (i = 0; i < data.dbreturn.length; i++) {
var latilongi = data.dbreturn[i].mapa.split(',');
var mapinha = {lat: parseFloat(latilongi['0']), lng: parseFloat(latilongi['1'])};
var marker = new google.maps.Marker({
position: mapinha,
html: '<div id="content"><h5 id="firstHeading" class="firstHeading">'+data.dbreturn[i].nome+'</h5></div>'
});
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}