谷歌地图API v3:允许在自定义OverlayView上使用默认上下文菜单



我有一个带有自定义覆盖的地图(基于https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/overlay-popup)。

自定义覆盖内容包括一个链接/锚标记,我希望允许用户右键单击链接并选择"在新选项卡中打开">,但右键单击会被地图取消,我无法确定如何防止这种行为。

如果将上面链接的自定义覆盖的示例与默认的"信息窗口"进行比较https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/infowindow-simple您可以注意到,当右键单击"Hello World"文本时,自定义覆盖不会显示上下文菜单,而信息窗口会显示上下文菜单。在开发工具中,我注意到信息窗口上有一个事件处理程序,它以某种方式允许上下文菜单(删除该处理程序会停止上下文菜单的出现(,但由于它在缩小的谷歌地图代码中,我无法理解它

我尝试过以下几种:

google.maps.event.addListener(map, 'rightclick', function (e) {
var event = e.ya;
var element = event.target;
if (element.nodeName === "A") {
event.stopImmediatePropagation();
event.stopPropagation();
return true;
}
});

代码已经执行,但仍然没有上下文菜单。相反,当地图随着鼠标移动时,它会打断地图上的一些东西,就好像我仍然按住鼠标一样(看起来我阻止了鼠标向上处理程序(。

我还尝试在自定义覆盖上设置preventMapHitsFrom(https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView.preventMapHitsAndGesturesFrom),这使得上面的内容不再被激发,但仍然没有上下文菜单。

我还能够自己附加一个事件处理程序(原谅jQuery(:

$(document).on("contextmenu", ".map-popup__link", function (e) {
e.stopImmediatePropagation();
return true;
});

但再次不确定如何防止活动被取消。我还试图在同一个元素上触发一个新事件,但这只是创建了一个循环(显然(,而没有解决问题。

基于https://stackoverflow.com/a/7414594/1397352我已将Popup.prototype.onAdd功能修改为

Popup.prototype.onAdd = function () {
this.getPanes().floatPane.appendChild(this.containerDiv);
this.getPanes().overlayMouseTarget.appendChild(this.containerDiv);
// set this as locally scoped var so event does not get confused
var me = this;
// Add a listener - we'll accept clicks anywhere on this div, but you may want
// to validate the click i.e. verify it occurred in some portion of your overlay.
google.maps.event.addDomListener(this.containerDiv, 'contextmenu', function () {
google.maps.event.trigger(me, 'contextmenu');
});
};

事件处理程序中的断点被击中,但上下文菜单再次不显示。

有人用这个来处理自定义覆盖吗?

由于MrUpsidown的评论,我能够在(存档的(信息框库中找到解决方案:https://github.com/googlemaps/v3-utility-library/blob/master/archive/infobox/src/infobox.js#L231

看起来我第一次尝试时很接近,但应该设置event.cancelBubble = true;

最终解决方案:

Popup.prototype.onAdd = function () {
this.getPanes().floatPane.appendChild(this.containerDiv);
// This handler allows right click events on anchor tags within the popup
var allowAnchorRightClicksHandler = function (e) {
if (e.target.nodeName === "A") {
e.cancelBubble = true;
if (e.stopPropagation) {
e.stopPropagation();
}
}
};
this.contextListener_ = google.maps.event.addDomListener(this.containerDiv, "contextmenu", allowAnchorRightClicksHandler);
};
Popup.prototype.onRemove = function () {
if (this.contextListener_) {
google.maps.event.removeListener(this.contextListener_);
this.contextListener_ = null;
}
if (this.containerDiv.parentElement) {
this.containerDiv.parentElement.removeChild(this.containerDiv);
}
};

参见https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/overlay-popup对于弹出代码的剩余部分

最新更新