google-maps - 更改 Google map 以重复使用单个信息窗口,而不是创建多个

标签 google-maps google-maps-api-3

我有一个越来越复杂的谷歌地图,它绘制了数千个点并将它们聚集在一起。当用户单击其中一个 map 标记时,我打开了一个信息窗口,这一切都很好。但是,我想做的一项改进是在打开新信息窗口时强制关闭所有其他信息窗口,以便一次只能打开 1 个信息窗口。

我已经尝试在监听器函数中添加一些代码 (if (infowindow) infowindow.close();) 来执行此操作,但我认为问题更广泛,因为我目前正在为每个标记创建一个信息窗口,并且无法访问打开新事件的其他信息窗口。因此,通过阅读这方面的内容,最好只使用一个信息窗口而不是多个信息窗口。

问题是,代码处于我能真正理解的边缘,到目前为止,我做这件事的实验已经破坏了一切。

我目前的代码如下:

var _iconCenter = new google.maps.MarkerImage('/css/img/map-marker.png',
  new google.maps.Size(38, 48),
  new google.maps.Point(0,0),
  new google.maps.Point(19, 44));

var shadow = new google.maps.MarkerImage('/css/img/map-marker-shadow.png',
  new google.maps.Size(57, 49),
  new google.maps.Point(0,0),
  new google.maps.Point(7, 44));

var _icon = '/css/img/map-marker-purple.png';
var infowindow;
var markersArray = [];
var map;
var currentPosition = 0;
var currentmarker;
var firstload = true;
var maploaded = false;
var interval = 5000;
var geocoder;

var stylez = [];

function initialize(items,loop,zoom) {
  geocoder = new google.maps.Geocoder();
  if (items.length > 0) {
    var latlng = new google.maps.LatLng(items[0].Lat, items[0].Lng);
    var myOptions = {
      zoom: zoom,
      center: latlng,
      //mapTypeControl: false,
      streetViewControl: false,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById("map"), myOptions);
    map.setOptions({styles: stylez});

    for (var i = 0; i < items.length; i++) {
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(items[i].Lat, items[i].Lng),
        title: items[i].Title,
        icon: _icon,
        shadow: shadow,
        infocontent: items[i].Description
      });
      marker.setMap(map);
      attachListener(marker,'marker:'+i);
      markersArray.push(marker);
    }


    //set style options for marker clusters (these are the default styles)
    mcOptions = {
      gridSize: 44
    }


    var markerCluster = new MarkerClusterer(map, markersArray, mcOptions);
    google.maps.event.addListener(map, "tilesloaded", function () {
      if(loop == true){
        SetLoop();
      }
    });


    function attachListener(marker,content){
      google.maps.event.addListener(marker, "click", function () {
        var infowindow = new google.maps.InfoWindow();
        map.setCenter(new google.maps.LatLng(marker.getPosition().lat(), marker.getPosition().lng()));
        infowindow.setContent(content);
        infowindow.open(map,this);
      });
    }    

  }
}


function SetLoop() {
//This will fire everytime map loads or recenteres
  maploaded = true;
  if (firstload) {
    firstload = false;
    Recenter();
  }
}


function Recenter() {
  //If previous iteration is not loaded completely, wait to avoid errors
  //It could happen for slow internet connection
  if (maploaded) {
    maploaded = false;
  } else {
    //keep adding 1 second to interval for slow connection till page loads
    interval = interval + 1;
    setTimeout("Recenter()", interval);
    return;
  }

  if (infowindow != null && currentmarker != null) {
    //currentmarker.icon = _icon;
    currentmarker.icon = _iconCenter;
    currentmarker.setMap(map);
    infowindow.close(map, currentmarker);
  }

  markersArray[currentPosition].icon = _iconCenter;
  markersArray[currentPosition].setMap(map);
  map.setCenter(new google.maps.LatLng(markersArray[currentPosition].getPosition().lat(), markersArray[currentPosition].getPosition().lng()));

  infowindow = new google.maps.InfoWindow({
    content: markersArray[currentPosition].infocontent,
    size: new google.maps.Size(50, 50)
  });
  infowindow.open(map, markersArray[currentPosition]);
  currentmarker = markersArray[currentPosition];
  if (currentPosition >= markersArray.length - 1) {
    currentPosition = 0;
  } else {
    currentPosition++;
  }
  if (markersArray.length > 1) {
    setTimeout("Recenter()", interval);
  }
}

是重新使用信息窗口的最佳方式还是可以以其他方式执行此操作?任何帮助我在这里指出正确的方向将不胜感激,谢谢大家!

最佳答案

从函数 attachListener() 中删除“var infowindow”声明。如果在函数内部声明它,它将成为函数的本地实例,并且每次执行函数时都会创建一个新实例。所以:

function attachListener(marker,content){
      google.maps.event.addListener(marker, "click", function () {

      // marker.getPosition() already returns a google.maps.LatLng() object
      map.setCenter(marker.getPosition());
      infowindow.close();
      infowindow.setContent(content);
      infowindow.open(map,this);
      });
    }    

而是将其声明为全局变量:

var _icon = '/css/img/map-marker-purple.png';
var infowindow = new google.maps.InfoWindow();
//...etc

这样整个应用程序中只有一个 infowindow 对象

关于google-maps - 更改 Google map 以重复使用单个信息窗口,而不是创建多个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11984258/

相关文章:

google-maps - Google Maps Bubble模板

javascript - Google map v3 与 MeteorJS 加载同步问题

java - Android REQUEST_DENIED Google 地点 API

javascript - 谷歌地图使用地点 ID 添加标记

javascript - Google map API v3 - 如何检测客户端负载?

javascript - Google Maps Address 而不是 LatLng GeoCode

javascript - fitBounds 和 getZoom 表现不佳

javascript - Chrome 设备模式下 Google map 标记图标周围的空白区域

javascript - 如何在谷歌地图图表中使用动态图标

javascript - 如何从 Google 版本 map 中拖动的标记获取格式化地址