簡體   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