简体   繁体   English

Google Maps API事件侦听器优先级

[英]Google Maps API event listener priority

I have a map which has a google.maps.event.addListener set on the map object for click events to place a marker on the map. 我有一张地图,在map对象上设置了google.maps.event.addListener ,用于click事件以将标记放置在地图上。 Now I want to add a context menu to the markers, so am creating a custom overlay in the floatPane . 现在,我想向标记添加一个上下文菜单,因此在floatPane创建一个自定义叠加层。 Again google.maps.event.addListener is used to add a rightclick event to each marker to position and display the menu. 再次使用google.maps.event.addListenerrightclick事件添加到每个标记,以定位和显示菜单。

Once the menu is displayed I want it to be cleared by either a menu item being selected, escape being pressed, or a click on the map. 显示菜单后,我希望通过选择菜单项,按逃脱或单击地图来清除它。

The menu has a div for each items using jQuery .on to attach a click handler to them, whilst when the menu is displayed a keydown handler is attached to the document using .on to check for escape being pressed. 菜单上的每个项目都有一个div ,使用jQuery .onclick处理程序附加到它们上,而当菜单显示时,则使用.onkeydown处理程序附加到document以检查是否按下了转义.on These work as desired but I am unable to find a satisfactory solution to detecting a click on the map. 这些可以按需工作,但是我无法找到令人满意的解决方案来检测地图上的点击。

If I use google.maps.event.addListener on the map object to cancel the menu it works, but also registers with the listener to add a marker and event.stopPropagation() does not affect this. 如果我在map对象上使用google.maps.event.addListener来取消菜单,则该菜单有效,但还会向侦听器注册以添加标记,而event.stopPropagation()不会对此产生影响。 ie Cancelling the menu also adds a marker. 取消菜单也会添加一个标记。 I believe the Google API triggers the handlers in the order they were added with no way to change the priority. 我相信Google API会按添加处理程序的顺序触发处理程序,而无法更改优先级。

I have also tried using a jQuery .on handler on the div to which the map is attached. 我也尝试过在贴有地图的div上使用jQuery .on处理程序。 But if I use click or mouseup event it is triggered by the right click which adds the menu. 但是,如果我使用clickmouseup事件,则由添加菜单的右键单击触发。 ie The menu flashes on screen as it appears but immediately closes. 菜单在显示时在屏幕上闪烁,但立即关闭。 A mousedown event avoids this problem, but obviously still triggers the Google API handler to add a marker. mousedown事件可以避免此问题,但显然仍会触发Google API处理程序添加标记。 It also registers the click to drag the map to scroll it, which the Google API does not and would be the preferred behaviour. 它还注册单击以拖动地图以滚动地图,而Google API则不会,这将是首选行为。

So it seems to me there are only two solutions to this problem. 因此在我看来,这个问题只有两种解决方案。

One would be to cancel any handlers on the map when the menu is displayed, then re-add them once it closes. 一种方法是在显示菜单时取消地图上的所有处理程序,然后在关闭后重新添加它们。 This seems unnecessarily excessive though. 不过,这似乎不必要地过度。

The other is to make wrap the content of the handlers in a conditional statement to detect whether the menu is open. 另一种方法是将处理程序的内容包装在条件语句中,以检测菜单是否打开。 This could be either by using a global variable as a flag or adding a status property to the menu's object. 这可以通过使用全局变量作为标志,也可以将status属性添加到菜单的对象中。

But this would make the code less reusable and go against the point of having separate event handlers. 但这会使代码的可重用性降低,并且与具有单独的事件处理程序的观点背道而驰。 I may as well just put the code to close the menu in the original handler too. 我也可以将代码也关闭原始处理程序中的菜单。

Is there anything I am missing? 我有什么想念的吗? It does not seem to be too obscure a thing to want to do but the inability to set the priority of handlers in the Google API means either having to code the handlers around each other. 似乎并不太想做一件事情,但是无法在Google API中设置处理程序的优先级意味着要么必须相互编码处理程序。

For what it's worth, I believe your first approach (adding and removing handlers) is the "cleanest" (or most elegant?) approach. 对于它的价值,我相信您的第一种方法(添加和删除处理程序)是“最干净的”(或最优雅的方法)。

If you think of the handlers as only having use/meaning when the menu is present, from a conceptual perspective, there's no need for them to exist when the menu is not visible. 如果您认为处理程序仅在菜单出现时具有使用/含义,从概念上讲,当菜单不可见时就不需要它们存在。

If you bundle the event-wiring into the same function(s) or method(s) that handle the menu, then it becomes a self-contained, re-usable element that doesn't leave any "garbage" behind. 如果将事件接线捆绑到处理菜单的相同函数或方法中,则它将成为一个独立的,可重复使用的元素,不会留下任何“垃圾”。

Since I don't have your code in front of you, here's some pseudocode: 由于我前面没有您的代码,因此下面是一些伪代码:

function displayMenu() {
    $menu.show()
      .on('click', function() { /* etc */ });
}

function hideMenu() {
    $menu.hide()
       .off() // remove ALL event handlers
}

Or, even better, encapsulate it in an object: 或者,甚至更好地将其封装在一个对象中:

var menu = {
    show: function() {
       // ...
    }
    hide: function() {
       // ...
    }
};

Or you could use a jQuery function too (though I generally eschew jQuery when I'm working with a map API, just to keep the number of dependencies low). 或者,您也可以使用jQuery函数(尽管在使用地图API时通常会避开jQuery,只是为了保持较低的依赖关系数量)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM