关闭 Google Maps API v3 中的所有信息窗口

Posted

技术标签:

【中文标题】关闭 Google Maps API v3 中的所有信息窗口【英文标题】:Close all infowindows in Google Maps API v3 【发布时间】:2011-05-31 04:58:43 【问题描述】:

我正忙于一个脚本,该脚本将在我的网站上制作一个带有多个标记的谷歌地图画布。我希望当您单击标记时,会打开一个信息窗口。我已经这样做了,代码在此刻:

 var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = 
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    ;
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    function addMarker(map, address, title) 
     geocoder = new google.maps.Geocoder();
     geocoder.geocode(  'address': address, function(results, status) 
        if (status == google.maps.GeocoderStatus.OK) 
          map.setCenter(results[0].geometry.location);
          var marker = new google.maps.Marker(
     position: results[0].geometry.location,
              map: map,
              title:title
    );
    google.maps.event.addListener(marker, 'click', function() 
     var infowindow = new google.maps.InfoWindow();
            infowindow.setContent('<strong>'+title + '</strong><br />' + address);
             infowindow.open(map, marker);

          );
         else 
          alert("Geocode was not successful for the following reason: " + status);
        
     );
    
    addMarker(map, 'Address', 'Title');
 addMarker(map, 'Address', 'Title');

这 100% 有效。但现在我希望当一个信息窗口打开时,你想打开第二个,第一个自动关闭。但我还没有找到一种方法来做到这一点。 infowindow.close();不会有帮助的。有人有这个问题的例子或解决方案吗?

【问题讨论】:

【参考方案1】:

infowindow 是局部变量,在 close() 时窗口不可用

var latlng = new google.maps.LatLng(-34.397, 150.644);
var infowindow = null;

...

google.maps.event.addListener(marker, 'click', function() 
    if (infowindow) 
        infowindow.close();
    
    infowindow = new google.maps.InfoWindow();
    ...
);
...

【讨论】:

谢谢。我将我的代码从拥有多个 InfoWindows 更改为只有一个在每个 marker.click 上关闭/打开。像魅力一样工作。 @William,你有没有机会为你所做的事情发布一个 sn-p 代码并在这里分享? 完美运行 :-) 我将 SnazzyInfoWindow.js 用于信息窗口并尝试了此解决方案。谢谢。 检查this answer,如果这个对你没有帮助。对我来说更好。【参考方案2】:

声明全局变量:

var mapOptions;
var map;
var infowindow;
var marker;
var contentString;
var image;

intialize 中使用地图的addEvent 方法:

google.maps.event.addListener(map, 'click', function() 
    if (infowindow) 
        infowindow.close();
    
);

【讨论】:

【参考方案3】:

我有一个动态循环,它根据输入到 CMS 的数量创建 infowindows 和标记,所以我不想在每次事件点击时创建一个新的 InfoWindow() 并因请求而陷入困境,如果有的话。相反,我试图知道每个实例的特定 infowindow 变量将超出我所拥有的设置数量的位置,然后提示地图在打开正确的位置之前关闭所有这些位置。

我的位置数组被称为位置,所以我设置的 php 之前实际地图初始化以获取我的 infowindow 变量名称是:

for($k = 0; $k < count($locations); $k++) 
        $infowindows[] = 'infowindow' . $k; 
 

然后在初始化地图等之后,在脚本中我有一个 PHP foreach 循环使用计数器创建动态信息窗口:

//...javascript map initilization
<?php 
$i=0;
foreach($locations as $location) 

    ..//get latitudes, longitude, image, etc...

echo 'var mapMarker' . $i . ' = new google.maps.Marker(
          position: myLatLng' . $i . ',
          map: map,
          icon: image
      );';

echo 'var contentString' . $i . ' = "<h1>' . $title[$i] . '</h1><h2>' . $address[$i] . '</h2>' . $content[$i] .         '";'; 
echo 'infowindow' . $i . ' = new google.maps.InfoWindow( ';
echo '    content: contentString' . $i . '
          );';

echo 'google.maps.event.addListener(mapMarker' . $i . ', "click", function()  ';   
    foreach($infowindows as $window)   
        echo $window . '.close();'; 
    
        echo 'infowindow' . $i . '.open(map,mapMarker'. $i . ');
      );';

$i++; 

?>
...//continue with Maps script... 

所以,重点是,在调用整个地图脚本之前,我有一个数组,其中包含我知道在创建 InfoWindow() 时将输出的名称,例如 infowindow0, infowindow1, infowindow2, etc...

然后,在每个标记的click 事件中,foreach 循环会执行并关闭所有标记,然后再执行下一步打开它们。结果看起来像这样:

google.maps.event.addListener(mapMarker0, "click", function() 
    infowindow0.close();
    infowindow1.close();
    infowindow2.close();
    infowindow0.open(map,mapMarker0);

我想只是一种不同的做事方式......但我希望它可以帮助某人。

【讨论】:

维护 imo 的代码太糟糕了。为什么不用 php 打印一个 json 数组并将其提供给一些 javascript 代码【参考方案4】:

对于动态创建infowindows 的循环,声明一个全局变量

var openwindow;

然后在addListenerfunction 调用中(在循环中):

google.maps.event.addListener(marker<?php echo $id; ?>, 'click', function() 
if(openwindow)
    eval(openwindow).close();

openwindow="myInfoWindow<?php echo $id; ?>";
myInfoWindow<?php echo $id; ?>.open(map, marker<?php echo $id; ?>);
);

【讨论】:

能解释一下这里使用eval的目的吗? openwindow 是一个字符串,如果我们不使用 eval,那么语句将执行为 openwindow.close() 而不是 myInfoWindow1.close()。检查您在此处看到的错误消息:jsfiddle.net/ts3z6nw6/1 我的 infowindows 是通过 JS 添加的——我使用了相同的方法,在我的 forEach() 之外声明 openwindow,它使用 windows 创建标记。在我的代码中,我不需要使用 eval,因为 openwindow 已经是 openwindow 对象。 你在 Firefox 中测试过吗?我在 Firefox 中遇到错误。 我用这种方法取得了成功,除了我将 openWindow 初始化为一个信息窗口,所以不需要 eval 【参考方案5】:

我有类似下面的东西

function initMap()

    //...create new map here
    var infowindow;
    $('.business').each(function(el)
        //...get lat/lng
        var position = new google.maps.LatLng(lat, lng);
        var content = "contents go here";
        var title = "titleText";
        var openWindowFn;
        var closure = function(content, position).
            openWindowFn = function()
            
                if (infowindow)
                
                    infowindow.close();
                
                infowindow = new google.maps.InfoWindow(
                    position:position,
                    content:content
                );
                infowindow.open(map, marker);
            
        (content, position);
        var marker = new google.maps.Marker(
            position:position,
            map:map,
            title:title.
        );
        google.maps.event.addListener(marker, 'click', openWindowFn);
    

在我的理解中,使用这样的闭包可以在函数声明时捕获变量及其值,而不是依赖全局变量。因此,当稍后调用openWindowFn 时,例如在第一个标记上,contentposition 变量具有它们在each() 函数的第一次迭代期间所做的值。

我不确定openWindowFn 如何在其范围内拥有infowindow。我也不确定我做对了,但它可以工作,即使在一页上有多个地图(每张地图都有一个打开的信息窗口)。

如果有人有任何见解,请发表评论。

【讨论】:

【参考方案6】:

我鼓励您在使用 Google 地图时尝试goMap jQuery 插件。对于这种情况,您可以在创建标记时将 hideByClick 设置为 true:

$(function()  
    $("#map").goMap( 
        markers: [  
            latitude: 56.948813, 
            longitude: 24.704004, 
            html:  
                content: 'Click to marker', 
                popup:true 
             
        ,  
            latitude: 54.948813, 
            longitude: 21.704004, 
            html: 'Hello!' 
        ], 
        hideByClick: true 
    ); 
); 

这只是一个示例,它提供了许多功能,例如分组标记和操作信息窗口。

【讨论】:

【参考方案7】:

你应该点击你的地图 - $('#map-selector').click();

【讨论】:

【参考方案8】:

在处理标记簇时,这个对我有用。

var infowindow = null;

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

        if (infowindow) 
            infowindow.close();
        
        var markerMap = this.getMap();
        infowindow = this.info;
        this.info.open(markerMap, this);


    );

【讨论】:

【参考方案9】:

我已经头疼了一个小时试图关闭 infoWindow! 我的最终(和工作)选项是用 SetTimeout (几秒钟)关闭 infoWindow 这不是最好的方法......但它很容易工作

    marker.addListener('click', function() 
    infowindow.setContent(html);
    infowindow.open(map, this);

    setTimeout(function()
        infowindow.close();
    ,5000);

);

【讨论】:

【参考方案10】:

我的代码示例可能会有所帮助。我只在全局范围内设置了一个 infowindow 对象。然后使用 setContent() 在显示之前设置内容。

  let map;
  let infowindow;
  let dataArr = [
    
      pos:lat: -34.397, lng: 150.644,
      content: 'First marker'
    ,
    
      pos:lat: -34.340, lng: 150.415,
      content: 'Second marker'
    
  ];

  function initMap() 
    map = new google.maps.Map(document.getElementById('map'), 
      center: lat: -34.397, lng: 150.644,
      zoom: 8
    );
    // Set infowindow object to global varible
    infowindow = new google.maps.InfoWindow();
    loadMarker();
  

  function loadMarker()
    dataArr.forEach((obj, i)=>
      let marker = new google.maps.Marker(
        position: obj.pos,
        map: map
      );
      marker.addListener('click', function() 
        infowindow.close()
        infowindow.setContent(`<div> $obj.content </div>`)
        infowindow.open(map, marker);
      );
    )
  

【讨论】:

【参考方案11】:

在脚本标签开始后写下这一行。

previous_Window=null;

它将 100% 工作。通过使用此代码

 radius= circle.getRadius()/1000;
 radius_mile= circle.getRadius()/1609.344;

 newRadious = 'This Circle Radius Covers Approx ' + radius.toFixed(1) + ' Km'+' <br> This circle Radius Covers Approx '+ radius_mile.toFixed(1)+ 'Miles';
            var infoWindow= new google.maps.InfoWindow(
              content: newRadious
              );
 infoWindow.setContent(newRadious)
 infoWindow.setPosition(circle.getCenter());
 if (previous_Window) 
  previous_Window.close();

  infoWindow.open(map);
  previous_Window=infoWindow;

【讨论】:

【参考方案12】:

如果您有多个标记,您可以使用这个简单的解决方案在单击新标记时关闭以前打开的标记:

var infowindow = new google.maps.InfoWindow(
                maxWidth: (window.innerWidth - 160),
                content: content
            );

            marker.infowindow = infowindow;
            var openInfoWindow = '';

            marker.addListener('click', function (map, marker) 
                if (openInfoWindow) 
                    openInfoWindow.close();
                
                openInfoWindow = this.infowindow;
                this.infowindow.open(map, this);
            );

【讨论】:

以上是关于关闭 Google Maps API v3 中的所有信息窗口的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps API v3 infowindow 关闭事件/回调?

Google Maps API V3 中的 API 密钥是啥?

Google Maps API v3 中的 Javascript 错误 (RefererDeniedMapError)

在 Google Maps API v3 中只打开一个 InfoWindow

可以吗? GMap API V2 中的 clearOverlays() 到 Google Maps API V3?

如何更改 Google Maps API V3 中的图标颜色?