【发布时间】:2011-12-01 09:10:22
【问题描述】:
[UPDATE:] 这里是一个测试链接(如果你不想克隆 repo)http://jsfiddle.net/integralist/g9EPu/
当鼠标悬停在网络应用中的某些链接上时,我需要显示很多对话框/模式。
目录 (tl;dr)
- 我以前是怎么处理的
- 我最近如何尝试
- 哪个更好?
- 鼠标进入/离开呢?
我以前是怎么处理的
我通常这样做的方式是使用事件委托。
所以我将一个事件处理程序添加到容器中,然后检查相关元素是否成为目标,然后显示相关对话框。
我通常有一个对话框,我可以更改内容并重新定位(保存有许多不同的 HTML 标记)。
如果mouseover 事件(用于链接)被触发,那么我会显示对话框。
如果mouseout 事件(用于链接)被触发,那么我将隐藏对话框。
如果我mouseout 触发了事件处理程序的链接,那么我通常需要设置一个计时器来延迟隐藏对话框(足够长),这样我就可以将鼠标悬停在对话框上,该对话框本身会清除由@设置的计时器987654329@的链接。
然后我将mouseout 事件绑定到对话框,这样当用户将鼠标从对话框上移开时,我就可以隐藏对话框。
在这个阶段我遇到了两个问题,第一个几乎一直在发生,另一个是我最近注意到的一个边缘案例,这促使我尝试寻找更好的解决方案......
-
对话框有“x”个子元素,将鼠标滚动到子元素上会导致触发对话框的
mouseout事件,因此我需要检查该元素是否有父元素对话框本身,如果是,请不要尝试隐藏对话框。 -
在
元素上使用这种技术时,我发现当鼠标移动得太快时,不会触发 mouseout/over 事件。
我最近如何尝试
例如代码参见:https://github.com/Integralist/Mouse-Over-Out-Script(您应该能够克隆 repo 并在本地运行 index.html 文件以查看发生了什么)
但要简单解释一下……
我们将
mousemove事件绑定到document.documentElement元素(但如果需要,您可以在document.body 上执行此操作),然后我们存储鼠标位置的x/y 坐标。我们提供对“检查”方法的公共 API 访问,该方法让我们知道鼠标的位置是否在我们提供给“检查”的元素上方(我们测量元素尺寸并将其添加到其 x/y 坐标)。在上面的 repo 中,我们有一个日历,当特定日期有事件时,它会显示一个对话框。我们存储了所有有事件的
并且我们为每个 设置了一个计时器(这是因为我们需要不断调用 'check' 方法来查看那个 将鼠标悬停在上面)。 因此可能有 31+(因为我们显示的是下个月的前几天)显示对话框的机会,因此设置了 31+ 个计时器!
这个示例代码库现在可以工作,而我使用事件委托的第一个版本不是。
哪个更好?
我担心
mousemove版本的性能,因为它可能会使用大量计时器(取决于您在单个页面中需要多少对话框)。在我上面的日历示例中,最多可以运行 31 个以上的计时器!鼠标进入/离开呢?
我知道这些事件存在,如果所有浏览器都支持它,那么我可以安全地使用第一个版本,而不必检查导致错误的 mouseout/over 事件被触发的子元素。但无论如何,我不相信这会修复事件日历的示例,其中移动鼠标过快意味着浏览器不会触发
的 mouseout/over 事件。无论哪种方式,我知道您可以填充它,因为 jQuery 提供了 mouseenter/leave 事件,但是查看他们的代码我无法让它适用于我的脚本(因为我不使用 jQuery 或任何其他通用库 - ps,并且我不希望,所以请不要建议作为选项)。 非常感谢有人可以为我提供任何帮助/建议或指导。
【问题讨论】:
-
与其要求我们为您的文件制作本地副本来测试问题,不如您在jsfiddle.net 或jsbin.com 上为我们设置它
-
更新了链接,但如果你错过了,这里又是:jsfiddle.net/integralist/g9EPu
-
你能重组你的HTML吗?如果给定的 events 部分/div 元素是其关联的日历日期元素的子元素,这将使您的鼠标悬停事件管理更简单。如果在你的 JS 运行之前不能改变 HTML,你会考虑在之后改变它来达到同样的目的吗?
-
@thisgeek 我特意使用了一个弹出窗口来处理所有事件,因为另一种方法是将 31 多个弹出窗口元素(及其所有 HTML)加载到页面,这会将页面权重增加到不可接受的水平 (imo)。
-
标签: javascript modal-dialog dom-events mouseevent mousemove