使用 Google Maps API v3 禁用兴趣点信息窗口
Posted
技术标签:
【中文标题】使用 Google Maps API v3 禁用兴趣点信息窗口【英文标题】:Disable point-of-interest information window using Google Maps API v3 【发布时间】:2011-11-20 15:22:40 【问题描述】:我有一个带有信息气泡和自定义标记的自定义地图。当我放大诸如公园和大学之类的兴趣点时,当我单击时会打开一个信息窗口。如何禁用信息窗口?
我的代码如下:
var geocoder;
var map;
var infoBubble;
var dropdown = "";
var gmarkers = [];
var hostel_icon = new google.maps.MarkerImage('/resources/hostel_blue_icon.png',
new google.maps.Size(28,32),
new google.maps.Point(0,0),
new google.maps.Point(14,32));
var bar_icon = new google.maps.MarkerImage('/resources/bar_red_icon.png',
new google.maps.Size(28,32),
new google.maps.Point(0,0),
new google.maps.Point(14,32));
var icon_shadow = new google.maps.MarkerImage('/resources/myicon_shadow.png',
new google.maps.Size(45,32),
new google.maps.Point(0,0),
new google.maps.Point(12,32));
var customIcons =
hostel:
icon: hostel_icon,
shadow: icon_shadow
,
bar:
icon: bar_icon,
shadow: icon_shadow
;
function initialize()
var latlng = new google.maps.LatLng(12.82364, 26.29987);
var myMapOptions =
zoom: 2,
center: latlng,
panControl: false,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControlOptions: style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
navigationControlOptions: style: google.maps.NavigationControlStyle.DEFAULT
map = new google.maps.Map(document.getElementById("map_canvas"), myMapOptions);
infoBubble = new InfoBubble(
shadowStyle: 0,
padding: 0,
backgroundColor: 'rgb(57,57,57)',
borderRadius: 5,
arrowSize: 10,
borderWidth: 1,
maxWidth: 400,
borderColor: '#2c2c2c',
disableAutoPan: false,
hideCloseButton: true,
arrowPosition: 50,
backgroundClassName: 'phoney',
arrowStyle: 0
);
// Change this depending on the name of your php file
downloadUrl("phpsqlajax_genxml_2.php", function(data)
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++)
var bar_name = markers[i].getAttribute("bar_name");
var hostel_name = markers[i].getAttribute("hostel_name");
var street = markers[i].getAttribute("street");
var city = markers[i].getAttribute("city");
var postcode = markers[i].getAttribute("postcode");
var country = markers[i].getAttribute("country");
var page = markers[i].getAttribute("page");
var map_photo = markers[i].getAttribute("map_photo");
var type = markers[i].getAttribute("type");
var category = markers[i].getAttribute("category");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = '<div class="infowindow"><div class="iwPhoto" style="width: 105px; height: 65px;">' + "<a href='" + page + "'><img src='" + map_photo + "' alt=''/></a>" + '</div><div class="iwName" style="height: 24px;">' + "<a href='" + page + "'>" + hostel_name + "</a>" + '</div><div class="iwCategory" style="height: 15px;">' + category + '</div><div class="iwCity" style="height: 29px;">' + "<a href='" + page + "'>" + city + "</a>" + '<div class="iwArrow" style="width: 29px; height: 29px;">' + "<a href='" + page + "'><img src='/resources/arrow.png'/></a>" + '</div></div></div>';
var icon = customIcons[type] || ;
var marker = new google.maps.Marker(
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
title: bar_name
);
marker.bar_name = bar_name;
marker.category = category;
bindInfoBubble(marker, map, infoBubble, html, bar_name);
gmarkers.push(marker);
str = '<option selected> - Select a club - </option>';
for (j=0; j < gmarkers.length; j++)
str += '<option value="'+gmarkers[j].bar_name+'">'+gmarkers[j].bar_name+', '+gmarkers[j].category+'</option>';
var str1 ='<form name="form_city" action=""><select style="width:150px;" id="select_city" name="select_cityUrl" onchange="handleSelected(this);">';
var str2 ='</select></form>';
dropdown = str1 + str + str2;
document.getElementById("dd").innerHTML = dropdown;
);
function handleSelected(opt)
var indexNo = opt[opt.selectedIndex].index;
google.maps.event.trigger(gmarkers[indexNo-1], "click");
function bindInfoBubble(marker, map, infoBubble, html)
google.maps.event.addListener(marker, 'click', function()
infoBubble.setContent(html);
infoBubble.open(map, marker);
google.maps.event.addListener(map, "click", function ()
infoBubble.close();
);
);
function downloadUrl(url, callback)
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function()
if (request.readyState == 4)
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
;
request.open('GET', url, true);
request.send(null);
function parseXml(str)
if (window.ActiveXObject)
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
else if (window.DOMParser)
return (new DOMParser).parseFromString(str, 'text/xml');
function doNothing()
【问题讨论】:
这就是答案:这可以设置为 MapOptions 对象上的“样式”选项,它将应用于路线图、混合和地形图类型。正确使用的样式是: [ featureType: "poi", elementType: "labels", stylers: [ visibility: "off" ] ] 这不是真正的答案,因为这会完全从地图中删除标签。如何保持标签完好无损但禁用信息窗口? 【参考方案1】:查看可点击的其他答案:错误答案。
但是,如果您希望它可点击,但没有信息窗口,请在event
上调用stop()
以阻止信息窗口显示,但仍可以获得位置信息:
map.addListener('click', function (event)
// If the event is a POI
if (event.placeId)
// Call event.stop() on the event to prevent the default info window from showing.
event.stop();
// do any other stuff you want to do
console.log('You clicked on place:' + event.placeId + ', location: ' + event.latLng);
有关详细信息,请参阅the docs。
其他选项:完全删除 POI 图标,而不仅仅是 infoWindow:
var mapOptions =
styles: [ featureType: "poi", elementType: "labels", stylers: [ visibility: "off" ]]
;
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
【讨论】:
也许您因为您的答案不正确而投了反对票。 Google 实际上确实允许删除 POI。我刚刚做到了:styles: [ featureType: "poi", elementType: "labels", stylers: [ visibility: "off" ]]
@SweatCoder 问题是:“如何禁用 POI 的信息窗口” - 而不是“如何完全禁用 POI 图标”。您的代码完全禁用了 POI。
我不介意 POI,但我允许用户在地图上放置标记。当他们点击 POI 时,它永远不会注册我的点击事件。我用google.maps.event.addListener
做到这一点。为什么它不会在 POI 点击时触发?【参考方案2】:
只需设置地图样式以不显示兴趣点。这很简单,不会违反 Google 的服务条款。
例如
mapOpts =
styles: [
featureType: "poi",
stylers: [
visibility: "off"
]
]
;
$("#my-map").gmap(mapOpts).on("init", function(evt, map)
// do stuff with the initialised map
);
【讨论】:
【参考方案3】:您可以通过为兴趣点创建没有标签的样式地图来做到这一点。 这会保留地图上的地形和其他不错的信息,但会删除标记。
var remove_poi = [
"featureType": "poi",
"elementType": "labels",
"stylers": [
"visibility": "off"
]
]
map.setOptions(styles: remove_poi)
【讨论】:
太棒了!非常感谢! 这对我没有任何帮助。但这有效:styles: [ featureType: "poi", elementType: "labels", stylers: [ visibility: "off" ]]
【参考方案4】:
您可以考虑以下方法来禁用 POI 信息窗口:
function disablePOIInfoWindow()
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function ()
;
示例
function initMap()
var latlng = new google.maps.LatLng(40.713638, -74.005529);
var myOptions =
zoom: 17,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
;
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
disablePOIInfoWindow();
function disablePOIInfoWindow()
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function ()
alert('Ok');
;
google.maps.event.addDomListener(window, 'load', initMap);
html, body
height: 100%;
margin: 0;
padding: 0;
#map_canvas
height: 100%;
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<div id="map_canvas"></div>
上面的例子影响了所有的信息窗口,所以如果你只需要禁用 POI 信息窗口,那么我们可以引入 flag 来判断是否是 POI 信息窗口:
function disablePOIInfoWindow()
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function ()
if(this.get('isCustomInfoWindow'))
fnSet.apply(this, arguments);
;
示例
function initMap()
var latlng = new google.maps.LatLng(40.713638, -74.005529);
var myOptions =
zoom: 17,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
;
var infowindow = new google.maps.InfoWindow(
content: ''
);
infowindow.set('isCustomInfoWindow',true);
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
disablePOIInfoWindow();
google.maps.event.addListener(map, 'click', function (event)
infowindow.setContent(event.latLng.lat() + "," + event.latLng.lng());
infowindow.setPosition(event.latLng);
infowindow.open(map, this);
);
function disablePOIInfoWindow()
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function ()
if(this.get('isCustomInfoWindow'))
fnSet.apply(this, arguments);
;
//google.maps.event.addDomListener(window, 'load', initMap);
html, body
height: 100%;
margin: 0;
padding: 0;
#map_canvas
height: 100%;
<div id="map_canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
async defer></script>
【讨论】:
【参考方案5】:更新 Google Maps JavaScript API V3
您可以在 MapOptions 中将 clickableIcons 设置为 false。这将保留 POI 图标,但根据需要禁用信息窗口。
function initialize()
var myMapOptions = clickableIcons: false
更多细节在这里...
https://developers.google.com/maps/documentation/javascript/3.exp/reference#MapOptions
【讨论】:
@brendon 如果您选择此作为正确答案,这将对其他用户非常有帮助。这样一来,我们无需滚动浏览过于复杂的解决方案即可找到真正的解决方案,这是 API 提供的一个标志。 这就是为什么我总是滚动超过 3 个答案。这很好用!感谢分享:D【参考方案6】:如果您想要数据而不显示 InfoWindow HTML,您只需重新设计 google.maps.InfoWindow 的原型:
google.maps.InfoWindow.prototype.open = function ()
return this; //prevent InfoWindow to appear
google.maps.InfoWindow.prototype.setContent = function (content)
if (content.querySelector)
var addressHTML = content.querySelector('.address');
var address = addressHTML.innerHTML.replace(/<[^>]*>/g, ' ').trim();
var link = content.querySelector('a').getAttribute('href');
var payload =
header: 'event',
eventName: 'place_picked',
data:
name: content.querySelector('.title').innerHTML.trim(),
address: address,
link: link
;
console.log('emit your event/call your function', payload);
;
【讨论】:
【参考方案7】:我们可以通过处理 poi 上的点击来做到这一点,Google api 提供了一种方法来检测 POI 上的点击,根据article
根据上面的文章,这里有一个更简单的代码版本,可以用来阻止对 POI 的点击
function initMap()
map = new google.maps.Map(document.getElementById('map'), myOptions);
var clickHandler = new ClickEventHandler(map, origin);
var ClickEventHandler = function (map, origin)
this.origin = origin;
this.map = map;
this.map.addListener('click', this.handleClick.bind(this));
;
ClickEventHandler.prototype.handleClick = function (event)
//console.log('You clicked on: ' + event.latLng);
if (event.placeId)
//console.log('You clicked on place:' + event.placeId);
// Calling e.stop() on the event prevents the default info window from
// showing.
// If you call stop here when there is no placeId you will prevent some
// other map click event handlers from receiving the event.
event.stop();
【讨论】:
已经有很多不错的解决方案可以正常工作,请看看它们。您认为您的回答是否为这篇文章增加了一些重要的信息或质量?以上是关于使用 Google Maps API v3 禁用兴趣点信息窗口的主要内容,如果未能解决你的问题,请参考以下文章
在信息窗口中使用 Google Maps v3 禁用鼠标滚轮缩放
Google Maps API V3 中的 API 密钥是啥?
在 maps.google.com 上的缩放比在 Google Maps API v3 上更流畅