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

Posted

技术标签:

【中文标题】在 Google Maps API v3 中只打开一个 InfoWindow【英文标题】:Have just one InfoWindow open in Google Maps API v3 【发布时间】:2010-12-24 22:32:27 【问题描述】:

我只需要在我的 Google 地图上打开一个信息窗口。在打开新的 InfoWindows 之前,我需要关闭所有其他 InfoWindows。

谁能告诉我怎么做?

【问题讨论】:

你尝试了什么? 【参考方案1】:

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

【讨论】:

这不对,我的地图上最多可以打开 20 个信息窗口。顺便说一句,它是 v3。 好的,谢谢指正。我不知道它在版本 3 中发生了变化。【参考方案2】:

您需要跟踪您之前的@​​987654321@ 对象并在处理新标记上的点击事件时对其调用close 方法

注意 不需要在共享信息窗口对象上调用 close,使用不同的标记调用 open 将自动关闭原始对象。详情请见Daniel's answer。

【讨论】:

我知道这是一个旧的答案,而且 v3 API 在当时是晦涩难懂的......但实际上没有必要调用 close() 方法,如果使用单个 InfoWindow 对象.如果在同一对象上再次调用open() 方法,它将自动关闭。 @daniel-vassallo 感谢您的注意 :) 我相应地赞成您的回答,这是我认为最有用的。【参考方案3】:

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

这是一个简单的例子:

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);而不是“标记”。感谢分享您的解决方案。 我也这样做了,但是 infoWindow 在下一个标记上打开需要 +1 秒是正常的吗?有时它根本不打开。我使用完全相同的代码【参考方案4】:

您只需要创建一个InfoWindow 对象,保留对它的引用,并为所有标记重复使用 if。 Quoting from the Google Maps API Docs:

如果您希望一次只显示一个信息窗口(就像 Google 地图上的行为一样),您只需创建一个信息窗口,您可以根据地图事件(例如用户点击)将其重新分配给不同的位置或标记)。

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

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

那么InfoWindow 应该会在您单击新标记时自动关闭,而无需调用close() 方法。

【讨论】:

我也这样做了,但是 infoWindow 在下一个标记上打开需要 +1 秒是正常的吗?有时它根本不打开。我使用完全相同的代码 丹尼尔,好主意!!在此之前我试图手动同步,但它显示了奇怪的 javascript 错误(比如 main.js 中的“c is null”,或者类似(123 out of range 43))。【参考方案5】:

我遇到了同样的问题,但最好的答案并没有完全解决它,我在 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);                 

【讨论】:

传递 contentString 的方式对我很有用,谢谢。【参考方案6】:

基本上,您需要一个函数来保持对一个 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

【讨论】:

【参考方案7】:

有点晚了,但我设法通过将 infowindow 设为全局变量打开了一个 infowindow。

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

然后在监听器中

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

infowindow.open(map, this);

【讨论】:

非常适合我 :)【参考方案8】:

声明一个 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);
);

【讨论】:

【参考方案9】:

这样解决了:

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

【讨论】:

【参考方案10】:

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

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

    var infoWindows = [];
    

    将每个新的 infoWindow 存储在数组中,紧随 infoWindow = new...

    infoWindows.push(infoWindow);
    

    创建 closeAllInfoWindows 函数

    function closeAllInfoWindows() 
        for (var i=0;i<infoWindows.length;i++) 
            infoWindows[i].close();
        
    
    

    在您的代码中,在打开 infoWindow 之前调用 closeAllInfoWindows()。

问候,

【讨论】:

它可以工作,但不是一个很好的解决方案,因为您只是不断将信息窗口添加到数组中,因此可能会有一个数组多次出现相同的信息窗口。【参考方案11】:

使用 jQuery 实现此目的的一种智能简单的方法如下:

            google.maps.event.addListener(marker, 'click', function (e) 
                jQuery(".gm-ui-hover-effect").click();
                marker.info.open(map, this);
            );

它将单击工具提示中的所有关闭按钮。

【讨论】:

以上是关于在 Google Maps API v3 中只打开一个 InfoWindow的主要内容,如果未能解决你的问题,请参考以下文章

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

使用 Google Maps API v3 禁用兴趣点信息窗口

google maps js v3 api教程 -- 在地图上添加标记

在 Google Maps API v3 中删除标记

在 maps.google.com 上的缩放比在 Google Maps API v3 上更流畅

google maps js v3 api教程 -- 创建一个地图