显示信息窗口后阻止谷歌地图移动
Posted
技术标签:
【中文标题】显示信息窗口后阻止谷歌地图移动【英文标题】:Preventing Google Maps Move After Displaying Infowindow 【发布时间】:2013-08-26 15:07:23 【问题描述】:我正在尝试在 Google 地图上显示信息窗口。它显示完美,当您将鼠标悬停在标记上时,它会加载一个信息窗口,但地图会跳转以适合窗口。我不希望地图移动,而是信息窗口根据地图设置其位置。 Booking.com 有类似的东西。
编辑:添加了我的代码
这是我的代码的精简版。我从 AJAX 服务 获取所有信息,该服务返回 response
(其中还包含更多信息)。
$.ajax(
url: 'URL',
dataType: "json",
type: "GET",
success: function(response)
// delete all markers
clearOverlays();
var infowindow = new google.maps.InfoWindow();
for (var i = 0; i < response.length; i++)
item = response[i];
var marker = new google.maps.Marker(
position: new google.maps.LatLng(item.lat, item.lng),
map: map,
url: item.detail_url
);
markersArray.push(marker);
// display infowindow
google.maps.event.addListener(marker, "mouseover", (function(marker, item)
return function()
infowindow.setOptions(
content: 'SOME CONTENT HERE FOR INFOWINDOW'
);
infowindow.open(map, marker);
)(marker, item));
// remove infowindow
google.maps.event.addListener(marker, 'mouseout', function()
infowindow.close();
);
// marker click
google.maps.event.addListener(marker, 'click', function()
window.location.href = marker.url;
);
);
如下所示,第一张图片显示了显示在标记底部的信息窗口,而第二张显示了显示在标记顶部的信息窗口。地图不会移动,但 infowindow 会在地图边界内设置其位置。
【问题讨论】:
【参考方案1】:在设置信息窗口选项infowindow.setOptions
的声明中,添加以下选项以在显示信息窗口时禁用地图平移disableAutoPan : true
。
但是,这也意味着您需要计算可用于在地图上显示信息窗口的空间,并使用 position
选项为其指定位置。否则无法保证您的信息窗口在地图上完全可见。
https://developers.google.com/maps/documentation/javascript/reference#InfoWindowOptions
编辑:如何计算屏幕空间
我意识到我的建议非常含糊,即计算可用于设置信息窗口位置的屏幕空间,而您的部分问题是实际设置信息窗口的位置。因此,我提供了有关如何计算屏幕空间和调整信息窗口位置的答案的更新。
关键是首先将您的点从 LatLng 转换为像素,并找出地图上标记的像素坐标相对于地图中心的像素坐标。下面的 sn-p 演示了如何做到这一点。
getPixelFromLatLng: function (latLng)
var projection = this.map.getProjection();
//refer to the google.maps.Projection object in the Maps API reference
var point = projection.fromLatLngToPoint(latLng);
return point;
获得像素坐标后,您需要找出标记当前位于地图画布的哪个象限。这是通过将标记的 X 和 Y 坐标与地图进行比较来实现的,例如所以:
quadrant += (point.y > center.y) ? "b" : "t";
quadrant += (point.x < center.x) ? "l" : "r";
在这里,我根据它与地图中心的相对位置来确定该点是在地图的右下角、左下角、右上角还是左上角。请记住,这就是我们使用像素而不是 LatLng 值的原因,因为 LatLng 值总是会产生相同的结果 - 但实际上,标记可以位于地图画布的任何象限中,具体取决于平移。
一旦您知道标记位于哪个象限,您就可以为信息窗口提供偏移值以定位它,使其在地图上可见 - 如下所示:
if (quadrant == "tr")
offset = new google.maps.Size(-70, 185);
else if (quadrant == "tl")
offset = new google.maps.Size(70, 185);
else if (quadrant == "br")
offset = new google.maps.Size(-70, 20);
else if (quadrant == "bl")
offset = new google.maps.Size(70, 20);
//these values are subject to change based on map canvas size, infowindow size
一旦确定了偏移值,您就可以在调用infoWindow.open()
方法的任何侦听器上调整信息窗口的pixelOffset
。这是通过使用 infowindows 的 setOptions()
方法完成的:
infowindow.setOptions(pixelOffset : self.getInfowindowOffset(self.map, marker));
这是上述解决方案的有效JSFiddle example。
注意:您会注意到信息窗口上恼人的“箭头”显示您的信息窗口的位置,这是谷歌地图默认信息窗口设置的一部分,我找不到合适的方法摆脱它。有一个建议here,但我无法让它发挥作用。或者,您可以使用 infobox library 或 infobubble library - 为您提供更多样式选项。
【讨论】:
谢谢 Suvi Vignarajah。我知道disableAutoPan
,但问题是我无法计算地图上的房地产并使用position
选项为信息窗口提供位置。
@BurakErdem 我提供了一种方法,您可以使用它来计算屏幕空间,以便在我编辑的答案中相应地定位您的信息窗口。希望这能给你一些工作。
您的实现效果很好。我刚刚更新了您的代码 (jsfiddle.net/SJCNp/2) 以删除底部箭头。我知道这不是最好的解决方案,但它确实有效。有人可能想要添加额外的 CSS 来模仿 Google 地图信息窗口的功能。谢谢。
是的,通过 js 操作 DOM 可能不是最理想的方式 - 但它现在可以解决问题。
这个答案真是难得啊!很棒的工作。谢谢【参考方案2】:
Suvi Vignarajah 的回答很棒,但我不喜欢它是窗户的位置在边缘附近的不可预测性。
我对其进行了调整,使气泡像预期的那样粘在墙上:http://jsfiddle.net/z5NaG/5/
唯一的条件是你需要知道infoWindow的width
& height
,你可以很好的定位它。你可以通过地图的像素来解决这个问题。如果您不知道它,您可以在屏幕外初始化 InfoWindow,获取它的大小,然后在正确的位置再次打开它。丑陋但会工作。
在地图初始化时通过运行此函数首先在叠加层上进行初始化:
ourOverlay:null,
createOverlay:function()
this.ourOverlay = new google.maps.OverlayView();
this.ourOverlay.draw = function() ;
this.ourOverlay.setMap(this.map);
,
然后在open
事件中调整偏移量,如下所示:
getInfowindowOffset: function (map, marker)
// Settings
var iwWidth = 240; // InfoWindow width
var iwHeight = 190; // InfoWindow Height
var xOffset = 0;
var yOffset = 0;
// Our point of interest
var location = this.ourOverlay.getProjection().fromLatLngToContainerPixel(marker.getPosition());
// Get Edges of map in pixels: Sout West corner and North East corner
var swp = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getSouthWest());
var nep = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getNorthEast());
// Horizontal Adjustment
if(location.x<iwWidth/2)
xOffset= iwWidth/2-location.x;
else if(location.x>nep.x-iwWidth/2)
xOffset = (nep.x-iwWidth/2)-location.x ;
// Vertical Adjustment
if(location.y<iwHeight)
yOffset = location.y + iwHeight-(location.y-nep.y);
// Return it
return new google.maps.Size(xOffset, yOffset);
,
结果非常好,但这个三角形现在看起来不合适。
您可以使用InfoBox 删除底部的尖箭头:
GmapsManager.infowindow = new InfoBox(
content:'',
alignBottom: true,
closeBoxURL: "",
);
并使用以下代码设置气泡样式:
.infobox-popup
background: #fff;
-webkit-border-radius: 3px;
border-radius: 3px;
padding: 5px;
margin-left: -100px;
margin-bottom: 30px;
width: 200px;
-webkit-box-shadow: 0 0 1px 0 #595959;
box-shadow: 0 0 1px 0 #595959;
【讨论】:
哥们,你拯救了我的一天,如果你能修复损坏的链接将会很棒(我已经修复了信息框之一)以上是关于显示信息窗口后阻止谷歌地图移动的主要内容,如果未能解决你的问题,请参考以下文章