谷歌地图API v3 - 添加多个信息窗口

21

我有一个可用的Google地图JavaScript部分,但我曾经遇到问题。

我曾经的问题是只有一个信息窗口出现了,即最后一个。我在另一个堆栈线程上找到了解决方案,它起作用了。但我无法真正搞清楚为什么。我对JavaScript相当新手,所以希望有人能向我解释发生了什么变化以及如何更改。

以下是已经运行的代码:

function setMarkers(map, locations){
  for(var i = 0; i < locations.length; i++){
    var marker = locations[i];
    var latLng = new google.maps.LatLng(locations[i][1], locations[i][2]);
    var content = locations[i][0];
    var infowindow = new google.maps.InfoWindow();

    marker = new google.maps.Marker({
      position:latLng,
      map: map
    });

    google.maps.event.addListener(marker, 'click', function(content){
      return function(){
        infowindow.setContent(content);
        infowindow.open(map, this);
      }
    }(content));
  }
}

以下是原始损坏的代码(我将仅粘贴更改部分):

 google.maps.event.addListener(marker, 'click', function(){
      infowindow.setContent(content);
      infowindow.open(map, marker);
    });

现在,如果您愿意的话,我想知道:

  1. 返回函数(return fn)有什么作用?

  2. addListener的末尾添加(content)会发生什么?因为据我所见,在setContent属性中已经设置了内容。

谢谢!


谢谢您的编辑,这样看起来轻松多了。堆栈格式对我来说仍然有点新。 - Russ
1
你可能想要更改你的问题标题,它看起来太泛泛了。 - Nick Song
2个回答

48
不要在循环中重复使用你的infowindow...
你只需要一个infowindow 对象实例
将它移到循环外面,函数也是同样的道理。
在循环内,将其内容分配为相对于点击的marker相关内容

const locations = [
  {lat: 45.840196, lng: 15.964331, name: "Zagreb"},
  {lat: 43.514851, lng: 16.449083, name: "Split"},
  {lat: 42.645725, lng: 18.094058, name: "Dubrovnik"},
];

function initGoogleMap(){

  const infowindow = new google.maps.InfoWindow(); // Only one InfoWindow
  const map = new google.maps.Map(document.getElementById('map-canvas'), {
      zoom: 6,
      center: new google.maps.LatLng(45, 15)
  });
  
  function placeMarker( loc ) {
    const marker = new google.maps.Marker({
      position : new google.maps.LatLng( loc.lat, loc.lng ),
      map : map
    });
    google.maps.event.addListener(marker, 'click', function(){
        infowindow.close(); // Close previously opened infowindow
        infowindow.setContent(`<div id="infowindow">${loc.name}</div>`);
        infowindow.open(map, marker);
    });
  }
  
  // ITERATE ALL LOCATIONS. Pass every location to placeMarker
  locations.forEach( placeMarker );
  
}

google.maps.event.addDomListener(window, 'load', initGoogleMap);
html, body, #map-canvas { height: 100%; margin: 0px; }
#infowindow{ padding: 10px; }
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>


-1
由于某些原因,我不得不修改标记对象并在事件监听器函数内访问该数据。
点击事件函数的作用域是标记对象。
var infowindow = new google.maps.InfoWindow();

for(int i = 0; i < locations.length; i++){
    var latLng = new google.maps.LatLng(locations[i][1], locations[i][2]);
    var contentString = locations[i][0];

    marker = new google.maps.Marker({           
          position: latLng,
          map: map,
          contentString: contentString
    });
    marker.data = locations[i]; // adds object to marker object


    marker.addListener('click', function() {
        // read custom data in this.data   
        infowindow.setContent("<div id='infowindow'>"+ this.data[0] +"</div>");

        infowindow.open(map, this);
        map.setCenter(this.getPosition());
     });
}

你不需要那样做。相反,使用闭包 - MrUpsidown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接