Google Maps API v3:允许在自定义 OverlayView 上使用默认上下文菜单
Google Maps API v3: allow default context menu on custom OverlayView
我有一张带有自定义叠加层的地图(基于 https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/overlay-popup)。
自定义覆盖内容包括一个 link/anchor 标签和 我想允许用户右键单击 link 和 select "Open in new tab" ,但是地图取消了右键单击,我无法弄清楚如何防止这种行为。
如果您将上面的自定义覆盖示例 link 与默认信息 Window https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/infowindow-simple 进行比较,您会注意到自定义覆盖在正确时不显示上下文菜单单击 "Hello World" 文本,而信息 Window 确实显示上下文菜单。在开发工具中,我注意到 Info Window 上的事件处理程序以某种方式允许上下文菜单(删除该处理程序会停止出现上下文菜单),但是因为它在缩小的 Google 地图代码中我'我无法理解它。
我尝试了以下方法:
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;
}
});
代码已执行,但仍然没有上下文菜单。相反,当地图随鼠标移动时它会破坏地图上的某些东西,就好像我仍然按下鼠标一样(看起来我阻止了 mouseup 处理程序)。
我还尝试在自定义覆盖层 (https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView.preventMapHitsAndGesturesFrom) 上设置 preventMapHitsFrom
,这使得上面的不再触发,但仍然没有上下文菜单。
我也能够自己附加一个事件处理程序(请原谅 jQuery):
$(document).on("contextmenu", ".map-popup__link", function (e) {
e.stopImmediatePropagation();
return true;
});
但又不确定如何防止活动被取消。我还尝试在同一元素上触发一个新事件,但这只是创建了一个循环(显然)而没有解决问题。
基于
我已将 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 了解弹出代码的其余部分
我有一张带有自定义叠加层的地图(基于 https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/overlay-popup)。
自定义覆盖内容包括一个 link/anchor 标签和 我想允许用户右键单击 link 和 select "Open in new tab" ,但是地图取消了右键单击,我无法弄清楚如何防止这种行为。
如果您将上面的自定义覆盖示例 link 与默认信息 Window https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/infowindow-simple 进行比较,您会注意到自定义覆盖在正确时不显示上下文菜单单击 "Hello World" 文本,而信息 Window 确实显示上下文菜单。在开发工具中,我注意到 Info Window 上的事件处理程序以某种方式允许上下文菜单(删除该处理程序会停止出现上下文菜单),但是因为它在缩小的 Google 地图代码中我'我无法理解它。
我尝试了以下方法:
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;
}
});
代码已执行,但仍然没有上下文菜单。相反,当地图随鼠标移动时它会破坏地图上的某些东西,就好像我仍然按下鼠标一样(看起来我阻止了 mouseup 处理程序)。
我还尝试在自定义覆盖层 (https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView.preventMapHitsAndGesturesFrom) 上设置 preventMapHitsFrom
,这使得上面的不再触发,但仍然没有上下文菜单。
我也能够自己附加一个事件处理程序(请原谅 jQuery):
$(document).on("contextmenu", ".map-popup__link", function (e) {
e.stopImmediatePropagation();
return true;
});
但又不确定如何防止活动被取消。我还尝试在同一元素上触发一个新事件,但这只是创建了一个循环(显然)而没有解决问题。
基于
我已将 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 了解弹出代码的其余部分