简体   繁体   English

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

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

[UPDATE:] here is a link to test (if you don't want to clone the repo) http://jsfiddle.net/integralist/g9EPu/ [更新:] 这里是一个测试链接(如果你不想克隆 repo) http://jsfiddle.net/integralist/g9EPu/

I've got a lot of dialogs/modals that need to be displayed when mousing over certain links in a web app.当鼠标悬停在 Web 应用程序中的某些链接上时,我有很多对话框/模式需要显示。

Table of content (tl;dr)目录 (tl;dr)

  • How I used to do handle it我以前是怎么处理的
  • How I've tried it recently我最近如何尝试
  • Which is better?哪个更好?
  • What about mouseenter/leave?鼠标进入/离开怎么样?

How I used to do handle it我以前是怎么处理的

The way I usually do this is to use event delegation.我通常这样做的方法是使用事件委托。

So I add one event handler to a container and then check for the relevant element to become the target and then display the relevant dialog.所以我向容器添加一个事件处理程序,然后检查相关元素是否成为目标,然后显示相关对话框。

I normally have one dialog which I change the content for and re-position (saves having lots of different HTML mark-up).我通常有一个对话框,我可以更改内容并重新定位(保存许多不同的 HTML 标记)。

If the mouseover event (for the link) gets triggered then I display the dialog.如果mouseover事件(对于链接)被触发,那么我会显示对话框。

If the mouseout event (for the link) gets triggered then I hide the dialog.如果mouseout事件(对于链接)被触发,那么我会隐藏对话框。

If I mouseout of the link which triggered the event handler then I normally need to set a timer to delay hiding the dialog (just long enough) so I can then mouseover the dialog which itself clears the timer set by the mouseout of the link.如果我mouseout触发事件处理程序的链接,那么我通常需要设置一个计时器来延迟隐藏对话框(足够长的时间),以便我可以将鼠标悬停在对话框上,该对话框本身会清除由链接的mouseout设置的计时器。

I then have a mouseout event bound to the dialog so I can then hide the dialog when the user rolls their mouse off the dialog.然后我有一个mouseout事件绑定到对话框,这样当用户将鼠标滚离对话框时,我可以隐藏对话框。

There are two problems I've encountered at this stage, the first happens practically all the time and the other is an edge case I noticed recently which prompted me to try and find a better solution...在这个阶段我遇到了两个问题,第一个几乎一直发生,另一个是我最近注意到的一个边缘情况,这促使我尝试找到更好的解决方案......

  1. The dialog has 'x' number of child elements and rolling the mouse over a child element causes the mouseout event for the dialog to be triggered hence I need to put in checks to see if the element has a parent which is the dialog itself and if so then don't try to hide the dialog.对话框有“x”个子元素,将鼠标滚动到子元素上会导致触发对话框的mouseout事件,因此我需要检查该元素是否有一个父元素,即对话框本身,如果所以不要试图隐藏对话框。

  2. When using this technique on a <table> element I've found that when the mouse moves too quickly the mouseout/over events don't get triggered.在 <table> 元素上使用这种技术时,我发现当鼠标移动太快时,鼠标移出/悬停事件不会被触发。

How I've tried it recently我最近如何尝试

For example code see: https://github.com/Integralist/Mouse-Over-Out-Script (you should be able to just clone the repo and run the index.html file locally to see what's happening)例如代码请参见: https : //github.com/Integralist/Mouse-Over-Out-Script (您应该能够克隆 repo 并在本地运行 index.html 文件以查看发生了什么)

But to give a brief explanation...但要给一个简短的解释......

We bind a mousemove event to the document.documentElement element (but you could do it on the document.body if you wanted) and then we store the x/y co-ordinates of the mouse position.我们将mousemove事件绑定到document.documentElement元素(但如果您愿意,您可以在 document.body 上进行),然后我们存储鼠标位置的 x/y 坐标。 We provide public API access to a 'check' method which lets us know if the position of the mouse is over the element we've provided to 'check' (we measure the elements dimensions and add those onto its x/y co-ordinates).我们提供对“检查”方法的公共 API 访问,该方法让我们知道鼠标的位置是否在我们提供给“检查”的元素上(我们测量元素尺寸并将其添加到其 x/y 坐标上)。

In the above repo we have a calendar which shows a dialog whenever a particular date has an event on.在上面的 repo 中,我们有一个日历,当特定日期有事件时,它会显示一个对话框。 We're storing all <td>'s that have an event and we set-up a timer for each of those <td>'s (this is because we need to keep calling the 'check' method to see if that <td> has the mouse over it).我们正在存储所有具有事件的 <td> 并为每个 <td> 设置一个计时器(这是因为我们需要不断调用“检查”方法以查看 <td > 将鼠标悬停在其上)。

So potentially there could be 31+ (because we're showing the first few days of the following month) opportunities for a dialog to be shown and so 31+ timers set!因此,可能有 31 次以上(因为我们显示的是下个月的前几天)显示对话框的机会,因此设置了 31 次以上的计时器!

This example repo works now, where as the first version where I was using event delegation wasn't.这个示例 repo 现在可以工作,因为我使用事件委托的第一个版本不是。

Which is better?哪个更好?

I'm worried about performance on the mousemove version because it can potentially use a lot of timers (depending on how many dialogs you need in a single page).我担心mousemove版本的性能,因为它可能会使用很多计时器(取决于单个页面中需要多少个对话框)。 In my calendar example above there is up to 31+ timers that could be running!在我上面的日历示例中,最多可以运行 31 个以上的计时器!

What about mouseenter/leave?鼠标进入/离开怎么样?

I know these events exist and if all browsers supported it then I could safely use the first version and not have to check for child elements causing erroneous mouseout/over events to be triggered.我知道这些事件存在,如果所有浏览器都支持它,那么我可以安全地使用第一个版本,而不必检查导致错误的 mouseout/over 事件被触发的子元素。 But regardless I don't believe this would have fixed the example with the event calendar where moving the mouse too quickly was meaning the mouseout/over events for the <td>'s weren't being triggered by the browser.但无论如何,我不相信这会修复事件日历的示例,其中将鼠标移动得太快意味着 <td> 的鼠标悬停/悬停事件没有被浏览器触发。 Either way, I know you can polyfill this as jQuery provides mouseenter/leave events but looking through their code I couldn't get that to work for my script (as I don't use jQuery or any other general purpose library - ps, and I don't wish to, so please do not suggest that as an option).无论哪种方式,我都知道您可以对它进行 polyfill,因为 jQuery 提供了 mouseenter/leave 事件,但是查看他们的代码我无法让它为我的脚本工作(因为我不使用 jQuery 或任何其他通用库 - ps,和我不希望,所以请不要建议将其作为一种选择)。

Many thanks for any help/advice or guidance someone can provide me.非常感谢有人可以为我提供的任何帮助/建议或指导。

The dialog has 'x' number of child elements and rolling the mouse over a child element causes the mouseout event for the dialog to be triggered hence I need to put in checks to see if the element has a parent which is the dialog itself and if so then dont try to hide the dialog.对话框有“x”个子元素,将鼠标滚动到子元素上会导致触发对话框的 mouseout 事件,因此我需要检查该元素是否有一个父元素,即对话框本身,如果所以不要试图隐藏对话框。

To solve this: in your event code, simply use the function "isAncestor" (see below)要解决这个问题:在您的事件代码中,只需使用函数“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 );
}

So in your mouseout code for your element (let's call it "itemElement"), you'd check it like:所以在你的元素的 mouseout 代码中(我们称之为“itemElement”),你会像这样检查它:

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

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

相关问题 在JavaScript中处理点/小向量的最有效方法是什么? - What is the most efficient way to handle points / small vectors in JavaScript? 使用JavaScript评估字符串是否是回文符的最有效方法是什么? - What's the most efficient way to evaluate if a string is a palindrome using Javascript? 在Java中通过字符串的最有效方式是什么? - What is the most efficient way to go through string's chars in Javascript? 在JavaScript中,将标签转换为链接的最有效方法是什么? - In javascript, what's the most efficient way to I turn tags into links? 比较 javascript 中的 2 个元素的最有效方法是什么? - What's the most efficient way to compare 2 elements in javascript? 在Javascript中创建嵌套div的最有效方法是什么? - What is the most efficient way to create nested div's in Javascript? 等待Java中异步函数调用的最有效方法是什么? - What's the most efficient way to wait for an asynchronous function call in Javascript? 在Javascript中声明函数的最有效方法是什么? - What is the most efficient way to declare functions in Javascript? 在Javascript中实现GroupBy的最有效方法是什么? - What is the most efficient way to implement GroupBy in Javascript? 在 Javascript 中反转数组的最有效方法是什么? - What is the most efficient way to reverse an array in Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM