繁体   English   中英

在 JavaScript 中处理显示对话框/模式的最有效方法是什么?

[英]What's the most efficient way to handle displaying a dialog/modal in JavaScript?

[更新:] 这里是一个测试链接(如果你不想克隆 repo) http://jsfiddle.net/integralist/g9EPu/

当鼠标悬停在 Web 应用程序中的某些链接上时,我有很多对话框/模式需要显示。

目录 (tl;dr)

  • 我以前是怎么处理的
  • 我最近如何尝试
  • 哪个更好?
  • 鼠标进入/离开怎么样?

我以前是怎么处理的

我通常这样做的方法是使用事件委托。

所以我向容器添加一个事件处理程序,然后检查相关元素是否成为目标,然后显示相关对话框。

我通常有一个对话框,我可以更改内容并重新定位(保存许多不同的 HTML 标记)。

如果mouseover事件(对于链接)被触发,那么我会显示对话框。

如果mouseout事件(对于链接)被触发,那么我会隐藏对话框。

如果我mouseout触发事件处理程序的链接,那么我通常需要设置一个计时器来延迟隐藏对话框(足够长的时间),以便我可以将鼠标悬停在对话框上,该对话框本身会清除由链接的mouseout设置的计时器。

然后我有一个mouseout事件绑定到对话框,这样当用户将鼠标滚离对话框时,我可以隐藏对话框。

在这个阶段我遇到了两个问题,第一个几乎一直发生,另一个是我最近注意到的一个边缘情况,这促使我尝试找到更好的解决方案......

  1. 对话框有“x”个子元素,将鼠标滚动到子元素上会导致触发对话框的mouseout事件,因此我需要检查该元素是否有一个父元素,即对话框本身,如果所以不要试图隐藏对话框。

  2. 在 <table> 元素上使用这种技术时,我发现当鼠标移动太快时,鼠标移出/悬停事件不会被触发。

我最近如何尝试

例如代码请参见: https : //github.com/Integralist/Mouse-Over-Out-Script (您应该能够克隆 repo 并在本地运行 index.html 文件以查看发生了什么)

但要给一个简短的解释......

我们将mousemove事件绑定到document.documentElement元素(但如果您愿意,您可以在 document.body 上进行),然后我们存储鼠标位置的 x/y 坐标。 我们提供对“检查”方法的公共 API 访问,该方法让我们知道鼠标的位置是否在我们提供给“检查”的元素上(我们测量元素尺寸并将其添加到其 x/y 坐标上)。

在上面的 repo 中,我们有一个日历,当特定日期有事件时,它会显示一个对话框。 我们正在存储所有具有事件的 <td> 并为每个 <td> 设置一个计时器(这是因为我们需要不断调用“检查”方法以查看 <td > 将鼠标悬停在其上)。

因此,可能有 31 次以上(因为我们显示的是下个月的前几天)显示对话框的机会,因此设置了 31 次以上的计时器!

这个示例 repo 现在可以工作,因为我使用事件委托的第一个版本不是。

哪个更好?

我担心mousemove版本的性能,因为它可能会使用很多计时器(取决于单个页面中需要多少个对话框)。 在我上面的日历示例中,最多可以运行 31 个以上的计时器!

鼠标进入/离开怎么样?

我知道这些事件存在,如果所有浏览器都支持它,那么我可以安全地使用第一个版本,而不必检查导致错误的 mouseout/over 事件被触发的子元素。 但无论如何,我不相信这会修复事件日历的示例,其中将鼠标移动得太快意味着 <td> 的鼠标悬停/悬停事件没有被浏览器触发。 无论哪种方式,我都知道您可以对它进行 polyfill,因为 jQuery 提供了 mouseenter/leave 事件,但是查看他们的代码我无法让它为我的脚本工作(因为我不使用 jQuery 或任何其他通用库 - ps,和我不希望,所以请不要建议将其作为一种选择)。

非常感谢有人可以为我提供的任何帮助/建议或指导。

对话框有“x”个子元素,将鼠标滚动到子元素上会导致触发对话框的 mouseout 事件,因此我需要检查该元素是否有一个父元素,即对话框本身,如果所以不要试图隐藏对话框。

要解决这个问题:在您的事件代码中,只需使用函数“isAncestor”(见下文)

/*
 * element = the "target" in your mouseout event handler
 * other = the node you really want to check if you're over
 */
isAncestor: function(element, other)
{
    while ( element && element != other ) element = element.parentNode;
    return ( element != null && element != undefined );
}

所以在你的元素的 mouseout 代码中(我们称之为“itemElement”),你会像这样检查它:

//We're really mousing out, close dialog
if ( !isAncestor( mouseOutEvent.target, itemElement ) )
{
    ...do something ...
}

暂无
暂无

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

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