我可以在 Google Maps API v3 中仅删除 POI 的弹出气泡吗?

Can I remove just the popup bubbles of POI's in Google Maps API v3?

提问人:Andrew G. Johnson 提问时间:10/31/2011 最后编辑:QuantumAndrew G. Johnson 更新时间:11/8/2022 访问量:21658

问:

因此,我正在开发一个新的 Web 应用程序,该应用程序非常关注地图。使用 Google Maps API v3 并且对它非常满意,但注意到兴趣点 (POI) 会自动冒泡,其中包含更多详细信息和指向 Google 地方页面的链接。我不想要这些。这是我的代码:

map = new google.maps.Map(document.getElementById("map"), {
    center:new google.maps.LatLng(default_latitude,default_longitude),
    zoom:11,
    mapTypeId:google.maps.MapTypeId.ROADMAP,
    mapTypeControl:false,
    panControl:false
});

我知道您可以完全删除 POI。这是我的代码:

map = new google.maps.Map(document.getElementById("map"),{
    center:new google.maps.LatLng(default_latitude,default_longitude),
    zoom:11,
    mapTypeId:google.maps.MapTypeId.ROADMAP,
    mapTypeControl:false,
    panControl:false,
    styles:[{
        featureType:"poi",
        elementType:"labels",
        stylers:[{
            visibility:"off"
        }]
    }]
});

这完全消除了一切,我仍然希望看到标签,因为我认为它们带来了价值,但只是认为泡沫太分散注意力了。

作为参考,这里是我想删除的气泡:

Example

这是完全删除 POI 的相同地图:

Example

javascript 谷歌地图 api-3

评论

0赞 tim 7/13/2012
您是否尝试过使用第二个 mapTile 图层,它只是一个 256x256 的空白 png?您可以将其设置为默认的 mapType,如果幸运的话,它的 z-index 位于 POI 的信息窗口触发器上方。我不打算尝试,因为我还有其他担心:)但说真的,我记得我曾经用第二层构建了一张地图,在路线图的顶部有自定义地图图块,如果我没记错的话,它导致一些标记事件不再被捕获......
0赞 Kalnode 8/25/2022
另一种方法:监听地图点击事件(就像我们所有人一样),如果存在,则用于禁止本机 infoWindow。然后,您可以执行自己的逻辑,例如跟踪的自定义 infoWindow。请参见:stackoverflow.com/a/61310243/4378314event.placeIdevent.stop()

答:

2赞 jeffreynolte 10/31/2011 #1

如果 Google 不允许您通过 API 直接访问它们(我认为您应该能够访问它们),我会使用 firebug 检查元素并用于删除这些样式display:none !important;

评论

0赞 Andrew G. Johnson 10/31/2011
我可能正在使用自定义气泡,因此这可能对我不起作用。此外,我怀疑有一种方法可以禁用它们[听起来你也这样做]只是在 Google 文档中找不到任何关于这一点的细节
0赞 jeffreynolte 10/31/2011
没有与自定义气泡关联的样式,当过去受到 Gmap API 选项的限制时,我只是选择了使用 CSS 删除不需要的元素的选项。
0赞 Andrew G. Johnson 10/31/2011
如果您愿意,该 API 允许您添加自己的气泡,其中包含您自己的数据。我是说我可能会使用该功能,因此禁用所有气泡对我来说可能不是一个选项。
0赞 Tomas 12/2/2011
我正在研究这种可能性,这是一个死胡同。POI 不是使用 DOM 完成的(没有 divs,没有 html 地图区域......POI 可点击区域必须以某种方式仅使用 javascript 进行处理,可能只是通过处理地图单击事件。因此,尝试以这种方式破解它很难甚至不可能。
-3赞 duncan 10/31/2011 #2

建议你看看我在这里给出的答案:如何删除默认标记?

var myStyles =[
    {
        featureType: "poi",
        elementType: "labels",
        stylers: [
              { visibility: "off" }
        ]
    }
];

var myOptions = {
    zoom: 10,
    center: homeLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    styles: myStyles 
};
5赞 Roman Goyenko 11/10/2011 #3

编辑:好的,看起来谷歌实施了一个解决方案,看看xomena的答案。

好的,在到处搜索之后,看起来您不能只在禁用点击的情况下显示 POI,您可以在此处查看更多讨论:

http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/f1ac9ad4da3606fe/3975bbda46904ae7?lnk=gst&q=disable+poi#3975bbda46904ae7

特别是这种交流:


你好

是否有可能使 POI 可见但不可点击?

谢谢 洛伦佐


克里斯·布罗德富特

不幸的是,不是洛伦佐。您需要应用地图样式才能隐藏 POI 标签:

[ { featureType: “poi”, elementType: “labels”, stylers: [ { 可见性: “关闭” } ] } ]

(或者只是隐藏业务 poi,“poi.business”)


这来自 Google 地图开发人员,因此这意味着您无法禁用弹出窗口,只能禁用 POI。

评论

1赞 Andrew G. Johnson 11/10/2011
你有没有运行过自己的代码?我做到了,你点击机场图标,得到一个信息窗口
4赞 Roman Goyenko 11/10/2011
我当然做到了。那么,您的目标是在单击时不显示气泡?我以为你在显示地图时会自动得到气泡。让我来研究一下。顺便说一句,给那些试图帮助你并花费数小时做这件事的人给 -1 并不酷。
3赞 Andrew G. Johnson 11/11/2011
我没有否决你的努力,我否决了一个忽略我问题的答案
1赞 Tomas 12/2/2011
@Romario,第二个街区以“Chris Broadfoot ...” 开头只是重复 OP 在他的问题中的代码。
0赞 miguev 6/13/2016
为了获得可靠的用户体验,请在 MapOptions 中使用新的 clickableIcons 属性(请参阅下面的 xomena 答案)
8赞 Tomas 12/3/2011 #4

找到解决方法!它很脏,所以如果谷歌改变了一些东西,它可能会停止工作,但它有效!

您必须找到 google 放置 infoWindows for POI 的层。幸运的是,这些层与用于用户 infoWindows 的层不同。诀窍是找到合适的层。阴影层可以很容易地找到,但 infoWindow 层是在创建一些 POI infoWindow 之后创建的,因此您必须像 google 一样侦听同一 div 上的点击事件。然后,您可以通过 z-index 或图像 url 找到 POI infoWindow 图层,但这还没有经过很好的测试......请注意,如果谷歌更改了 z-index,它将停止工作......

var lis = google.maps.event.addListener(my_map, 'tilesloaded', function () {

    $('*').filter(function () { return $(this).css('z-index') == 104 }).remove();
        // remove layer for POI infoWindow shadow - has z-index: 104

    var eventDiv = $(my_map.getDiv()).children().children()[0];
        // this div is used by google to handle events

    $(eventDiv).click(function clickHandler() {
        var timeout = 100;
        var attempts = 20;
        setTimeout(function timeoutHandler() {
            // there are 2 ways how to find POI infoWindow layer
            // 1st way - by the z-index
            var poiInfoLayer = $('*').filter(function () { 
                return $(this).css('z-index') == 169 || 
                       $(this).css('z-index') == 248 
            });
            // 2nd way - by the images :-)
            // but not tested much - it may also find normal infoWindows!
            //var poiInfoLayer = $('[src*="/mapfiles/iw3.png"]').parent().parent();

            if (poiInfoLayer.length) {
                    poiInfoLayer.remove();
                    $(eventDiv).unbind('click', clickHandler);
            }
            else {
                    if (attempts > 0) {
                            setTimeout(timeoutHandler, timeout);
                            attempts--;
                    }
            }

        }, timeout);
    });
    google.maps.event.removeListener(lis);
});

评论

2赞 Tomas 12/8/2011
请解释一下反对票的原因。我花了几个小时才弄清楚这一点!
0赞 tim 7/13/2012
我喜欢它并投了赞成票 - 但是人们,你必须知道这就像删除网页中的付费广告一样。与执行此操作的浏览器插件不同,如果您有足够的流量,谷歌可以将您的域列入黑名单。
0赞 Nail 7/18/2014
这对我不起作用。这很正常,因为它是 3 年前写的。我找到了另一种解决方法,发布在这里: stackoverflow.com/a/24817995/943535
1赞 miguev 6/13/2016
为了获得可靠的用户体验,请在 MapOptions 中使用新的 clickableIcons 属性(请参阅下面的 xomena 答案)
8赞 jsmarkus 8/13/2012 #5

自 Google Maps API 更新以来,不再有效。

我终于找到了!

这是演示:http://jsfiddle.net/fbDDZ/14/(单击“打开”或POI不执行任何操作,单击“请打开”打开InfoWindow)

这个想法是修补 InfoWindow.prototype.open,以便允许它接受第三个参数。谷歌没有通过它,但我们应该通过。

代码:

function fixInfoWindow() {
    var proto = google.maps.InfoWindow.prototype,
        open = proto.open;
    proto.open = function(map, anchor, please) {
        if (please) {
            return open.apply(this, arguments);
        }
    }
}

Google 在 POI 上打开 InfoWindow,如下所示:

myInfoWin.open(map, poiMarker)

窗口不会打开,因为谷歌没有说“请”。这就是我们应该打开信息窗口的方式:

myInfoWin.open(map, poiMarker, true);

评论

1赞 thom_nic 2/23/2013
我希望这项工作会,但是当我尝试使用它并且它似乎不起作用时,似乎从未调用过修补版本。我肯定会在其他所有内容加载后打电话。openfixInfoWindow
2赞 gdonald 2/26/2013
这不再起作用,proto.open 永远不会被调用。该演示也不再有效:jsfiddle.net/fbDDZ/14 有人知道新方法吗?谢谢。
1赞 jsmarkus 3/5/2013
好吧,所以他们在 Maps API 3.12 中更改了它......坏消息,但我会研究解决方法。感谢您的举报。
1赞 Rob Porter 4/10/2013
它也被修补回 3.11,但 3.10 目前仍然允许这个技巧。我对此的担忧是,谷歌通常会在移动设备上禁用这种行为,但它似乎仍然发生在 Android PhoneGap 应用程序中。
0赞 miguev 6/13/2016
为了获得可靠的用户体验,请在 MapOptions 中使用新的 clickableIcons 属性(请参阅下面的 xomena 答案)
24赞 jsmarkus 10/31/2013 #6

编者注:这个答案一直适用到3.23版本。自 2016 年发布 3.24 版以来,您可以使用 clickableIcons 地图选项。请看xomena的回答

版本 ~3.12 修复演示

这是一个再次起作用的新补丁。我已经用 3.14 版对其进行了测试。

现在我们要打补丁而不是 .set()open()

function fixInfoWindow() {
    // Here we redefine the set() method.
    // If it is called for map option, we hide the InfoWindow, if "noSuppress"  
    // option is not true. As Google Maps does not know about this option,  
    // its InfoWindows will not be opened.

    var set = google.maps.InfoWindow.prototype.set;

    google.maps.InfoWindow.prototype.set = function (key, val) {
        if (key === 'map' && ! this.get('noSuppress')) {
            console.warn('This InfoWindow is suppressed.');
            console.log('To enable it, set "noSuppress" option to true.');
            return;
        }

        set.apply(this, arguments);
    }
}

您所要做的是将选项设置为您自己的选项以打开它们,例如:noSuppresstrueInfoWindow

var popup = new google.maps.InfoWindow({
    content: 'Bang!',
    noSuppress: true
});

popup.setPosition(new google.maps.LatLng(-34.397, 150.644));

popup.open(map);

艺术

var popup = new google.maps.InfoWindow({
    content: 'Bang!',
});

popup.set('noSuppress', true);
popup.setPosition(new google.maps.LatLng(-34.397, 150.644));

popup.open(map);

评论

1赞 Kasheftin 2/19/2014
这真的很酷!使用您的代码,使用 POI 做任何事情都非常简单。例如,在这里,我向 POI infoWindow 添加了自定义按钮:jsfiddle.net/kasheftin/935Km。添加日志记录信息并观察每个内部方法的调用堆栈非常简单。在这里,我为google.maps.InfoWindow.prototype做了这件事:jsfiddle.net/kasheftin/935Km/1
0赞 Markus Hofmann 12/27/2014
如果您使用 InfoBox 插件之类的东西,则设置该选项是多余的。只要您通过 InfoBox 打开自定义信息窗口,就不会调用修补的窗口。我自己用 Google Maps API v3 测试了这一点。noSuppressset
1赞 miguev 6/13/2016
为了获得可靠的用户体验,请在 MapOptions 中使用新的 clickableIcons 属性(请参阅下面的 xomena 答案)
16赞 xomena 5/7/2016 #7

从版本 3.24 开始,Maps JavaScript API 在 MapOptions 对象中有一个属性 clickableIcons:

https://developers.google.com/maps/documentation/javascript/3.exp/reference#MapOptions

可以使用此属性通过将 clickableIcons 属性设置为 false 来关闭地图上的可单击图标。还存在一个 setClickableIcons() 方法。

请看这个例子: http://jsbin.com/liyamecoqa/edit?html,output

0赞 divisible 11/8/2022 #8

是的,总而言之,如果你想“删除”弹出窗口,你可以只使用:

clickableIcons: false

用于 Map Options 对象。但是,如果你想有一个弹出窗口,但没有“在谷歌地图上查看”标签,你可以使用一个笨拙的CSS技巧:

google-map {
  .view-link {
    display: none !important;
  }
}

这是我的要求,而且很有效!

如果要定义哪些图标/图钉(元素或标签,无论您如何称呼它)应该可见,您可以使用此站点生成具有地图设置的正确 JSON: https://mapstyle.withgoogle.com/