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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4539905/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:51:11  来源:igfitidea点击:

Close all infowindows in Google Maps API v3

javascriptgoogle-maps-api-3

提问by Tom

I am busy with a script that will make a google maps canvas on my website, with multiple markers. I want that when you click on a marker, a infowindow opens. I have done that, and the code is at the moment:

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

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

This works 100%. But now i want that when one infowindow is open, and you want to open the second, the first one automaticly closes. But i haven't found a way to do that. infowindow.close(); won't help. Has someone an example or a solution to this problem?

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

回答by

infowindow is local variable and window is not available at time of close()

infowindow 是局部变量,并且 window 在 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();
    ...
});
...

回答by rajquest

Declare global variables:

声明全局变量:

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

In intializeuse the map's addEventmethod:

intialize使用地图的addEvent方法:

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

回答by Binod Kalathil

For loops that creates infowindowsdynamically, declare a global variable

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

var openwindow;

var openwindow;

and then in the addListenerfunction call (which is within the loop):

然后在addListener函数调用中(在循环中):

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

回答by RCNeil

I had a dynamic loop that was creating the infowindowsand markers based on how many were input into the CMS, so I didn't want to create a new InfoWindow()on every event click and bog it down with requests, if that ever arose. Instead, I tried to know what the specific infowindowvariable for each instance was going to be out of the set amount of locations I had, and then prompt Maps to close all of them before it opened the correct one.

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

My array of locations was called locations, so the PHP I set up beforethe actual maps initilization to get my infowindowvariable names was:

我的位置数组称为位置,因此我在实际地图初始化之前设置的 PHPinfowindow是:

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

Then after initialzing the map and so forth, in the script I had a PHP foreachloop creating the dynamic info windows using a counter:

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

//...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... 

So, the point is, before I called the entire map script, I had an array with the names I knew were going to be outputted when an InfoWindow()was created, like infowindow0, infowindow1, infowindow2, etc...

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

Then, on the clickevent for each marker, the foreachloop goes through and says close all of them before you follow through with the next step of opening them. It turns out looking like this:

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

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

Just a different way of doing things I suppose... but I hope it helps someone.

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

回答by Joe

I have a sample of my code that maybe can help. I had set only one infowindow object at global scope. Then use setContent() to set the content before show it.

我有一个我的代码示例,可能会有所帮助。我在全局范围内只设置了一个 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);
      });
    })
  }

回答by rwilson04

I have something like the following

我有类似以下的东西

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

In my understanding, using a closure like that allows the capturing of variables and their values at the time of function declaration, rather than relying on global variables. So when openWindowFnis called later, on the first marker for example, the contentand positionvariable have the values they did during the first iteration in the each()function.

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

I'm not really sure how openWindowFnhas infowindowin its scope. I'm also not sure I'm doing things right, but it works, even with multiple maps on one page (each map gets one open infowindow).

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

If anyone has any insights, please comment.

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

回答by Steamer

I encourage you to try goMapjQuery plugin when working with Google Maps. For this kind of situation you can set hideByClick to true when creating markers:

我鼓励您在使用 Google 地图时尝试使用goMapjQuery 插件。对于这种情况,您可以在创建标记时将 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 
    }); 
}); 

This is just one example, it has many features to offer like grouping markers and manipulating info windows.

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

回答by Slava

You should have to click your map - $('#map-selector').click();

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

回答by Daniel Badro

When dealing with marker clusters this one worked for me.

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

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


    });

回答by gtamborero

I have been an hour with headache trying to close the infoWindow! My final (and working) option has been closing the infoWindow with a SetTimeout (a few seconds) It's not the best way... but it works easely

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

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

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

});