jQuery和OpenLayers之间的事件监听器冲突

时间:2016-03-24 01:09:43

标签: javascript user-interface jquery-ui javascript-events mouseevent

该应用程序是一个Web地图(OpenLayers 2),可以通过单击某些功能打开对话框。对话框由jQuery-ui处理。

错误:在调整对话框大小时,如果用户过快地拖动光标,则光标会超过对话框的大小更新。通常情况下这需要相当不稳定的动作,但由于这个应用程序的填充程度如何,我猜它有点慢。

但是jQuery和OpenLayers之间存在一些事件处理冲突。当光标在其他任何地方超过div时它很好,但如果它在地图上,则调整大小停止(如果你鼠标向上,停止拖动状态也没有注册,所以如果你返回到对话框,它会用鼠标调整大小运动)。

这意味着要扩展对话框,你必须有意地平滑地移动光标而不要太快,否则它会中断,这对于用户体验来说显然是个问题。

设置一个非常简单的jsfiddle(http://jsfiddle.net/a6uu5vav/),只需尝试快速拖动或调整对话框大小。可能会因计算机/浏览器而异,但在Chrome中对我有用(也就是说,无法正常工作)。

原因:jQuery-ui似乎将与拖动/调整大小相关的事件侦听器附加到document,因此无论鼠标超出div,该功能都应该有效。然而,OpenLayers还在其创建的所有内容上放置了大量的事件监听器。它使用event.stopPropagation(),因此只通知目标元素上的侦听器。

因此,当光标位于OpenLayers映射上时,它会触发目标的事件侦听器,但事件不会传播到resize侦听器。虽然评论stopPropagation()在技术上解决了它,但由于嵌套的OpenLayers是如何以及它如何为所有事件提供事件监听器,这使得它只是悬停在地图上非常慢。

我尝试使用对话框模式来测试它确实是冲突的事件侦听器。 Modal修复了调整大小问题,但我们不希望它是模态的。可能虽然“hacky”解决方案是拥有一个不可见的模态,并且在mousedown / up事件开始/结束拖动时出现/消失。

我的修复尝试:我进入jQuery-ui(在ui.mouse定义中)修改事件侦听器以在捕获时触发(而不是冒泡),因为它们被添加然后保证文件将被解雇。由于jQuery.bind()不支持,我转为老同学addEventListener(),为了保持一致性,我还将任何相关的unbind()更改为removeEventListener()

现在就是这样的事情,如果我只是这样做了,但仍然将onCapture的{​​{1}}参数设置为false,它的工作方式与以前完全一样 - 与resize bug一样正常工作。如果我为mousemove监听器将addEventListener() param更改为true(如果我将mouseup设置为true / false则无关紧要),从技术上讲,调整大小问题是固定的,但现在其他的东西都很糟糕。

它拖动/调整大小很好,但是在mouseup上,事件监听器似乎没有被移除(因此移动鼠标仍然拖动或调整对话框的大小),也无缘无故地移动。正在调用onCapture并且至少在那些行中删除了事件侦听器,我知道这不是回调引用问题,我已经测试过了。我认为他们正在被正确删除,但不知何故读了。似乎jQuery中有一些东西在鼠标上启动时必须首先以某种方式重新排列顺序,即使只是那一点完全抛弃它。

这可能是一个失败的游戏(即相对于bug严重性的总时间下沉)尝试“修补”jQuery-ui,但想知道是否可能有其他一些想法如何尝试解决这个问题。 / p>

1 个答案:

答案 0 :(得分:0)

唉,我觉得很傻。我的修复提示确实有效,但如果您将addEventListener()的{​​{1}}参数设置为true,则必须将onCapture中的onCapture参数设置为true。 / p>

对于原始问题的完整修复,您必须编辑jQuery-ui中的removeEventListener()bind()以及mousemove和mouseup到unbind()addEventListener()这两个定义都是removeEventListener()

onCapture=true$.ui.mouse._mouseDestroy()$.ui.mouse._mouseDown()

到目前为止,它似乎对我有用。