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


Answers:


151

您只需要创建一个InfoWindow对象,保留对其的引用,然后对所有标记重复使用。引用Google Maps API文档

如果您一次只希望显示一个信息窗口(如Google Maps上的行为),则只需创建一个信息窗口,您可以在地图事件(例如用户点击)时将其重新分配到其他位置或标记。

因此,您可能InfoWindow只想在初始化地图后立即创建对象,然后click按如下方式处理标记的事件处理程序。假设您有一个标记someMarker

google.maps.event.addListener(someMarker, 'click', function() {
   infowindow.setContent('Hello World');
   infowindow.open(map, this);
});

然后,InfoWindow当您单击新的标记而无需调用该close()方法时,会自动关闭。


我也这样做,但是在下一个标记上打开infoWindow大约需要+1秒是正常的吗?有时它根本无法打开。我使用完全相同的代码
MJB

丹尼尔,好主意!在此之前,我尝试手动进行同步,但是它显示了奇怪的javascript错误(例如main.js中的“ c为null”或类似内容(123超出了范围43))。
维克多

30

在范围之外创建您的信息窗口,以便您可以共享它。

这是一个简单的示例:

var markers = [AnArrayOfMarkers];
var infowindow = new google.maps.InfoWindow();

for (var i = 0, marker; marker = markers[i]; i++) {
  google.maps.event.addListener(marker, 'click', function(e) {
    infowindow.setContent('Marker position: ' + this.getPosition());
    infowindow.open(map, this);
  });
}

谢谢。使用“ this”解决了我的大部分问题。我仍然不明白如何在setContent中使用自定义内容。例如在标记循环中,我使用“ i”变量创建一个contentHtml变量并将其链接到数据库对象。如何将那个contentHtml变量传递给侦听器?
瑞安

以我为例,仅当我在infowindow.open(map,this);中使用“ this”时,窗口才会打开。而不是“标记”。Thx分享您的解决方案。
ownking 2012年

我也这样做,但是在下一个标记上打开infoWindow大约需要+1秒是正常的吗?有时它根本无法打开。我使用完全相同的代码
MJB

14

我有同样的问题,但是最好的答案并不能完全解决它,我在for语句中要做的就是使用与此当前标记相关的this。也许这可以帮助某人。

for(var i = 0; i < markers.length; i++){
    name = markers[i].getAttribute("name");
    address = markers[i].getAttribute("address");        
    point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));                                     
    contentString = '<div style="font-family: Lucida Grande, Arial, sans-serif;>'+'<div><b>'+ name +'</b></div>'+'<div>'+ address +'</div>';                    
    marker = new google.maps.Marker({                       
        map: map,
        position: point,
        title: name+" "+address,
        buborek: contentString 
    });                                     
    google.maps.event.addListener(marker, 'click', function(){
        infowindow.setContent(this.buborek); 
        infowindow.open(map,this); 
    });                                                         
    marker.setMap(map);                 
}

2
传递contentString的方式对我很有用,谢谢。
ownking 2012年

4

有点晚,但是我通过maken infowindow全局变量只打开了一个infowindow。

var infowindow = new google.maps.InfoWindow({});

然后在列表器中

infowindow.close();
infowindow = new google.maps.InfoWindow({   
    content: '<h1>'+arrondissement+'</h1>'+ gemeentesFiltered                           
});

infowindow.open(map, this);

1
对我来说很棒:)
lumos 2015年

4

声明一个globar,var selectedInfoWindow;并用它来保存打开的信息窗口:

var infoWindow = new google.maps.InfoWindow({
    content: content
});

// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
    //Check if there some info window selected and if is opened then close it
    if (selectedInfoWindow != null && selectedInfoWindow.getMap() != null) {
        selectedInfoWindow.close();
        //If the clicked window is the selected window, deselect it and return
        if (selectedInfoWindow == infoWindow) {
            selectedInfoWindow = null;
            return;
        }
    }
    //If arrive here, that mean you should open the new info window 
    //because is different from the selected
    selectedInfoWindow = infoWindow;
    selectedInfoWindow.open(map, marker);
});

0

处理新标记上的click事件时,需要跟踪先前的InfoWindow对象并在其上调用close方法

注意:不必在共享信息窗口对象上调用关闭,使用其他标记调用打开会自动关闭原始对象。有关详细信息,请参见Daniel的答案


我知道这是一个古老的答案,而当时v3 API还是晦涩难懂...但是close(),如果使用单个InfoWindow对象,则实际上不需要调用该方法。如果open()在同一对象上再次调用该方法,它将自动关闭。
丹尼尔·瓦萨洛

@ daniel-vassallo感谢您的来信:)我相应地提高了您的回答,这是我认为最有用的。
RedBlueThing 2010年

0

基本上,您需要一个保留对一个new InfoBox()=>的引用的函数,委派onclick事件。在创建标记(循环)时使用bindInfoBox(xhr, map, marker);

// @param(project): xhr : data for infoBox template
// @param(map): object : google.maps.map
// @param(marker): object : google.maps.marker
bindInfoBox: (function () {
    var options = $.extend({}, cfg.infoBoxOptions, { pixelOffset: new google.maps.Size(-450, -30) }),
        infoBox = new window.InfoBox(options);

    return function (project, map, marker) {
        var tpl = renderTemplate(project, cfg.infoBoxTpl); // similar to Mustache, Handlebars

        google.maps.event.addListener(marker, 'click', function () {
            infoBox.setContent(tpl);
            infoBox.open(map, marker);
        });
    };
}())

var infoBox被异步分配并保存在内存中。每次调用bindInfoBox()return函数都会被调用。也很方便通过infoBoxOptions只一次!

在我的示例中,map由于制表符事件延迟了初始化,因此我不得不在上添加一个额外的参数。

InfoBoxOptions


0

这是一种解决方案,不需要创建一个infoWindow即可重用它。您可以继续创建许多infoWindows,唯一需要做的是构建closeAllInfoWindows函数,并在打开新的infowindow之前调用它。因此,保留您的代码,您只需要:

  1. 创建一个全局数组来存储所有的infoWindows

    var infoWindows = [];
    
  2. 在infoWindow = new之后,将每个新的infoWindow存储在数组中。

    infoWindows.push(infoWindow);
    
  3. 创建closeAllInfoWindows函数

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. 在您的代码中,在打开infoWindow之前,调用closeAllInfoWindows()。

问候,


-1

这样解决:

function window(content){
    google.maps.event.addListener(marker,'click', (function(){
        infowindow.close();
        infowindow = new google.maps.InfoWindow({
            content: content
        });
        infowindow.open(map, this);
    }))
}
window(contentHtml);

-4

Google地图仅允许您打开一个信息窗口。因此,如果您打开一个新窗口,则另一个窗口会自动关闭。


2
那是不对的,我可以在地图上打开多达20个信息窗口。它是v3 btw。
leo

好的,谢谢您的纠正。我不知道它在第3版改变
基莫Puputti
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.