更改Google地图以重新使用单个infowindow,而不是创建多个 [英] Change Google maps to re-use single infowindow rather than creating multiple

查看:72
本文介绍了更改Google地图以重新使用单个infowindow,而不是创建多个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张越来越复杂的Google地图,它绘制了数千个点并对它们进行聚类。当用户点击其中一个地图标记时,我有一个infowindow开放,并且这一切都很好。然而,我想要做的一个改进是在打开一个新窗口时强制所有其他infowindows关闭,以便一次只打开一个infowindow。



我试过在侦听器函数中添加一些代码( if(infowindow)infowindow.close(); )来做到这一点,但我认为这个问题更广泛,目前正在为每个标记创建一个infowindow,并且无法访问该事件中的其他infowindows,这会打开一个新的标记。所以,从阅读这个文件来看,似乎有一个更好的主意,只有一个infowindow被重用,而不是很多。



麻烦的是,代码处于边缘我真正理解的,我迄今为止做的实验已经破坏了一切。



我现在的代码如下:

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

var shadow = new google.maps.MarkerImage('/ css / img / map-marker-shadow.png',
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 = [];

函数初始化(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);
}


//设置标记簇的样式选项(这些是默认样式)
mcOptions = {
gridSize:44
}


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


函数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);
});





$ b函数SetLoop(){
//每次映射加载或接收时,
maploaded = true;
if(firstload){
firstload = false;
Recenter();




函数Recenter(){
//如果以前的迭代未完全加载,请等待以避免错误
/ /它可能会发生互联网连接慢
if(maploaded){
maploaded = false;
} else {
//对于缓慢连接,直到页面加载$ b $ 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);
}
}

重新使用infowindow或以另一种方式做这件事可以吗?任何帮助指引我在这里正确的方向将非常感谢,谢谢你们!

解决方案

删除'var infowindow'声明来自函数attachListener()。如果你在函数内部声明它,它就会变成本地函数,并且你每次执行该函数时都会创建一个新的实例。所以:

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

// marker.getPosition()已经返回一个google.maps.LatLng()对象
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对象申请

I have an increasingly complex Google map which plots thousands of points and clusters them. I have an infowindow opening when the user clicks one of the map markers and it all works great. However, one improvement I'd like to make is to force all other infowindows to close when a new one is opened so that only 1 infowindow can be open at once.

I've tried adding some code (if (infowindow) infowindow.close();) into the listener function to do this, but I think the issue is wider in that I'm currently creating an infowindow for each marker, and there is no access to other infowindows on the event which opens a new one. So, from reading around this it would seem to be a better idea to have just one infowindow which gets reused rather than many.

Trouble is, the code is at the edge of what I can really understand, and my experiments in doing this so far have just broken everything.

The code I currently have is as follows:

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);
  }
}

Is the best way to re-use the infowindow or is it okay to do this another way? Any help in pointing me in the right direction here would be much appreciated, thanks folks!

解决方案

Remove the 'var infowindow' declaration from function attachListener(). If you declare it inside the function it becomes local to the function and you create a new instance each time you execute the function. so:

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);
      });
    }    

and instead, declare it as a global variable:

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

so that you have only one infowindow object in the whole application

这篇关于更改Google地图以重新使用单个infowindow,而不是创建多个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆