Google Maps:自动关闭打开的InfoWindows吗?


108

在我的网站上,我正在使用Google Maps API v3在地图上放置房屋标记。

除非您明确单击关闭图标,否则InfoWindows保持打开状态。意思是,如果将鼠标悬停在地图标记上,则一次可以打开2个以上的InfoWindows。

问题:我该如何做才能仅打开当前活动的InfoWindow并关闭所有其他InfoWindows?就是说一次打开的窗口不超过1个?


1
对我而言,最好只创建一个信息窗口并对其进行更新(它的内容等),打开和关闭以及传送信息。但是我很确定这种方法并不总是适用。
andrii 2011年

Answers:


153

InfoWindows 有一个close()函数。只需跟踪最后打开的窗口,并在创建新窗口时调用它的关闭函数即可。

该演示具有所需的功能。我在Maps API V3演示库中找到了它。


4
建议仅跟踪最近打开的窗口。看起来像一个没有脑子,但人们忘记了这些东西
雷米顿

1
我刚刚使用了完全相同的技术。谢谢克里斯。这对我来说是必要的,因为我使用的是InfoWindow对象数组,而不是循环遍历并获取相关信息的对象。每个InfoWindow都有其自己的单独更新信息,因此我发现此技术非常有用。
InterfaceGuy

2
“此演示”链接已断开
Brendan Whiting,

64

使用许多信息窗口的替代解决方案:将先前打开的信息窗口保存在变量中,然后在打开新窗口时将其关闭

var prev_infowindow =false; 
...
base.attachInfo = function(marker, i){
    var infowindow = new google.maps.InfoWindow({
        content: 'yourmarkerinfocontent'
    });

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

        prev_infowindow = infowindow;
        infowindow.open(base.map, marker);
    });
}

3
像这个。易于理解和实施
Aamir Afridi 2014年

6
原谅我的天真,但WTF是基础吗?
wordforthewise

我不明白为什么这不是Google Maps V3中的默认行为……
华盛顿先生

到目前为止,我发现的最好和最简单的解决方案。谢谢!
Irteza Asad '18

27
//assuming you have a map called 'map'
var infowindow = new google.maps.InfoWindow();

var latlng1 = new google.maps.LatLng(0,0);
var marker1 = new google.maps.Marker({position:latlng1, map:map});
google.maps.event.addListener(marker1, 'click',
    function(){
        infowindow.close();//hide the infowindow
        infowindow.setContent('Marker #1');//update the content for this marker
        infowindow.open(map, marker1);//"move" the info window to the clicked marker and open it
    }
);
var latlng2 = new google.maps.LatLng(10,10);
var marker2 = new google.maps.Marker({position:latlng2, map:map});
google.maps.event.addListener(marker2, 'click',
    function(){
        infowindow.close();//hide the infowindow
        infowindow.setContent('Marker #2');//update the content for this marker
        infowindow.open(map, marker2);//"move" the info window to the clicked marker and open it
    }
);

这会将信息窗口“移动”到每个单击的标记周围,实际上将其自身关闭,然后在其新位置重新打开(并平移以适合视口)。打开之前会更改其内容以提供所需的效果。适用于n个标记。


1
快速说明:重复调用infowindow.open()就足够了;不需要先关闭窗口。
埃里克·阮

3
@Eric,尽管您在技术上是正确的,但我注意到有一个错误有时会导致信息窗口显示在其最后位置。强制关闭先失败后说bug。
乔尔·梅隆

22

我的解决方案。

var map;
var infowindow = new google.maps.InfoWindow();
...
function createMarker(...) {
var marker = new google.maps.Marker({
     ...,
     descrip: infowindowHtmlContent  
});
google.maps.event.addListener(marker, 'click', function() {
    infowindow.setOptions({
        content: this.descrip,
        maxWidth:300
    });
    infowindow.open(map, marker);
});

3
这确实很优雅-仅使用一个信息窗口并更改内容可以避免跟踪/关闭上一个窗口。
尼克·F

该解决方案确实非常优雅,并且就像一个魅力。+1
塞巴斯蒂安·布赖特

9

通过此链接http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows/

Teo:最简单的方法是让InfoWindow对象的一个​​实例一次又一次地重复使用。这样,当您单击新标记时,infoWindow将从当前所在的位置“移动”到新标记。

使用其setContent方法将其加载正确的内容。


我不认为这适用,因为我使用的是Google Maps v3 API
Ted

另外,你链接的文章也没有演示超过1个标记
特德

我已经在多个站点中以相同的方式使用了一个信息窗口。单击一个,打开的将自动关闭。
基思·阿德勒

4
如何将多个标记与单个InfoWindow相关联?
泰德(Ted)2010年

7

为活动窗口声明一个变量

var activeInfoWindow; 

并将此代码绑定到标记侦听器中

 marker.addListener('click', function () {
    if (activeInfoWindow) { activeInfoWindow.close();}
    infowindow.open(map, marker);
    activeInfoWindow = infowindow;
});

谢谢,它确实适用于在地图上的任意位置单击。
Varinder Singh Baidwan

干杯,在所有建议中,这对我来说效果最好,并且是干净的AF。
马修·埃利斯

4

除了使用close()函数外,还有一种更简单的方法。如果使用InfoWindow属性创建变量,则在打开另一个变量时它将自动关闭。

var info_window;
var map;
var chicago = new google.maps.LatLng(33.84659, -84.35686);

function initialize() {
    var mapOptions = {
        center: chicago,
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    info_window = new google.maps.InfoWindow({
        content: 'loading'
    )};

createLocationOnMap('Location Name 1', new google.maps.LatLng(33.84659, -84.35686), '<p><strong>Location Name 1</strong><br/>Address 1</p>');
createLocationOnMap('Location Name 2', new google.maps.LatLng(33.84625, -84.36212), '<p><strong>Location Name 1</strong><br/>Address 2</p>');

}

function createLocationOnMap(titulo, posicao, conteudo) {            
    var m = new google.maps.Marker({
        map: map,
        animation: google.maps.Animation.DROP,
        title: titulo,
        position: posicao,
        html: conteudo
    });            

    google.maps.event.addListener(m, 'click', function () {                
        info_window.setContent(this.html);
        info_window.open(map, this);
    });
}

1
var map;
var infowindow;
...
function createMarker(...) {
    var marker = new google.maps.Marker({...});
    google.maps.event.addListener(marker, 'click', function() {
        ...
        if (infowindow) {
            infowindow.close();
        };
        infowindow = new google.maps.InfoWindow({
            content: contentString,
            maxWidth: 300
        });
        infowindow.open(map, marker);
    }
...
function initialize() {
    ...
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    ...
    google.maps.event.addListener(map, 'click', function(event) {
        if (infowindow) {
            infowindow.close();
        };
        ...
    }
}

谢谢,我需要在不单击标记时关闭信息窗口,因此仅在地图上
VRC

1

怎么样 -

google.maps.event.addListener(yourMarker, 'mouseover', function () {
        yourInfoWindow.open(yourMap, yourMarker);

    });

google.maps.event.addListener(yourMarker, 'mouseout', function () {
        yourInfoWindow.open(yourMap, yourMarker);

    });

然后,您只需将鼠标悬停在它上面,它就会自行关闭。


这是一个有趣的解决方法,但它无法回答问题,因此无法在仅触摸设备上使用。

1

我在顶部存储了一个变量,以跟踪当前正在打开哪个信息窗口,请参见下文。

var currentInfoWin = null;
google.maps.event.addListener(markers[counter], 'click', function() {      
    if (currentInfoWin !== null) {
        currentInfoWin.close(map, this); 
    }
    this.infoWin.open(map, this); 
    currentInfoWin = this.infoWin;  
}); 

[柜台]在这里做什么?

0

如果您在for循环中使用了许多标记(这是Django,请参见此处),这就是我使用的方法。您可以在每个标记上设置一个索引,并在每次打开窗口时设置该索引。关闭先前保存的索引:

markers = Array();
infoWindows = Array();
var prev_infowindow =false;
{% for obj in objects %}
var contentString = 'your content'
var infowindow = new google.maps.InfoWindow({
            content: contentString,
          });
var marker = new google.maps.Marker({
               position: {lat: {{ obj.lat }}, lng: {{ obj.lon }}},
               map: map,
               title: '{{ obj.name }}',
               infoWindowIndex : {{ forloop.counter0 }}
          });
google.maps.event.addListener(marker, 'click',
            function(event)
            {
           if( prev_infowindow ) {
               infoWindows[prev_infowindow].close();
                }
                prev_infowindow = this.infoWindowIndex;
                infoWindows[this.infoWindowIndex].open(map, this);
            }
        );

        infoWindows.push(infowindow);
        markers.push(marker);

      {% endfor %}

-1
var contentString = "Location: " + results[1].formatted_address;    
google.maps.event.addListener(marker,'click', (function(){ 
    infowindow.close();
    infowindow = new google.maps.InfoWindow({
        content: contentString
    });
    infowindow.open(map, marker);
}));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.