1. 程式人生 > >mouseover和mouseout多次出發解決方案。

mouseover和mouseout多次出發解決方案。

原文地址:http://litib.tk/2010/08/mouseover%E5%92%8Cmouseout%E5%A4%9A%E6%AC%A1%E8%A7%A6%E5%8F%91%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/



在用到mouseover和mouseout事件來作為事件觸發的條件,但是如果我們用做觸發的元素內部有其他的元素的時候當滑鼠移上的時候會反覆 的觸發mouseover和mouseout事件。因為內部元素在滑鼠移上的時候會向它的父物件派發事件,所以外面元素相當於也觸發了mouseover 事件。

為了阻止mouseover和mouseout的反覆觸發,這裡要用到event物件的一個屬性relatedTarget,這個屬性就是用來判斷 mouseover和mouseout事件目標節點的相關節點的屬性。簡單的來說就是當觸發mouseover事件時,relatedTarget屬性代 表的就是滑鼠剛剛離開的那個節點,當觸發mouseout事件時它代表的是滑鼠移向的那個物件。由於MSIE不支援這個屬性,不過它有代替的屬性,分別是 fromElement和toElement。

有了這個屬性,我們就能夠清楚的知道我們的滑鼠是從哪個物件移過來,又是要移動到哪裡去了。這樣我們就能夠通過判斷這個相關聯的物件是否在我們要觸發事件的物件的內部,或者是不是就是這個物件本身。通過這個判斷我們就能夠合理的選擇是否真的要觸發事件。

這裡我們還用到了一個用於檢查一個物件是否包含在另外一個物件中的方法,contains方法。MSIE和FireFox分別提供了檢查的方法,這裡封裝了一個函式。

複製程式碼 function contains(parentNode, childNode) { if (parentNode.contains) { return parentNode
!= childNode && parentNode.contains(childNode); } else { return!!(parentNode.compareDocumentPosition(childNode) &16); } } 複製程式碼

這個函式用於檢查一個物件是否被包含在我們的觸發物件裡面。

下面就是我們的重點了,我封裝了一個用於檢查滑鼠是否真正從外部移入或者移出物件的函式checkHover(e,target),這個函式需要傳入當前的事件物件和目標物件。

複製程式碼 function checkHover(e,target){
if (getEvent(e).type=="mouseover") { return!contains(target,getEvent(e).relatedTarget||getEvent(e).fromElement) &&!((getEvent(e).relatedTarget||getEvent(e).fromElement)===target); } else { return!contains(target,getEvent(e).relatedTarget||getEvent(e).toElement) &&!((getEvent(e).relatedTarget||getEvent(e).toElement)===target); } } function getEvent(e){ return e||window.event; } 複製程式碼

函式裡面用到的getEvent()函式用於在MSIE或者FF下返回一個可用的event物件,這裡你可以自己封裝成別的函式。

函式的邏輯很簡單,首先判斷事件的型別,這個主要是為了遷就MSIE,當是mouseover的時候relatedTarget在MSIE下應該是 fromElement,而mouseout則應該返回toElement,當然在FF下面就好辦了,都是同一個屬性relatedTarget。首先判 斷我們的relatedTarget是否在目標物件的內部,如果是的話則直接返回假如果不在內部的話則判斷是否是目標物件本身,如果是的話返回假,要是兩 種情況都不成立則返回真。

到這裡我們的主要工作做完了,有了這個函式我們在進行程式設計的時候只要在mouseover或者mouseout事件內部先檢查一下,再進行下一步操作就能輕鬆實現hover的效果。

複製程式碼 myElement.onmouseover=function(e){ if(checkHover(e,this)){ do someting... } } myElement.onmouseout=function(e){ if(checkHover(e,this)){ do someting... } } 複製程式碼