「模擬mouseenter和mouseleave」的來龍去脈

這個話題,以前已經聊過一次,昨天和同事再次聊起時,發現本身理解的依然不夠透徹,決定從新整理一次,我想從如下幾個方面聊下本身的理解:javascript

1. mouseenter和mouseleave什麼時候被觸發?java

2. 與mouseover和mouseout的區別是什麼?ide

3. 爲何要模擬?函數

4. 如何模擬?性能

 

一. mouseenter和mouseleave什麼時候被觸發

咱們來看下官方解釋(mouseentermouseleave):this

// onmouseenter:
Fires when the user moves the mouse pointer inside the boundaries of an object.
即:當鼠標移入元素對象的邊界以內時,激活該事件

// onmouseleave:
Fires when the user moves the mouse pointer outside the boundaries of the object.
即:當鼠標移出元素對象的邊界以外時,激活該事件

二. 與mouseover和mouseout的區別

官方站點在介紹mouseenter和mouseleave時,同時說明了與mouseover和mouseout的不一樣:spa

// onmouseenter vs onmouseover
Unlike the onmouseover event, the onmouseenter event does not bubble. In other words, the onmouseenter event does not fire when the user moves the mouse pointer over elements contained by the object, whereas onmouseover does fire.
即:onmouseenter不會冒泡,onmouseover則會,因爲這個差別,當鼠標在元素邊界內移動時,不會激活onmouseenter(只在鼠標進入元素邊界內時激活),但會激活onmouseover(當該元素包含子元素時)。

// onmouseleave vs onmouseout
同上,因爲存在冒泡的差別,致使了鼠標在元素邊界內移動時,會激活onmouseout(當該元素包含子元素時),但不會激活onmouseleave。

三. 爲何要模擬mouseenter和mouseleave?

緣由很簡單:相對於mouseover和mouseout,mouseenter和mouseleave具備性能優點(不會反覆觸發),但只有IE支持它。。。code

四. 如何模擬?

原理:監聽目標元素的mouseover和mouseout事件,只當鼠標移入目標元素時,才執行回調函數,忽略子元素上激活的mouseover 和mouseout事件。咱們經過事件對象的relatedTarget屬性,來判斷鼠標是移入/移出目標元素,仍是在目標元素內移動:對象

(1) 當mouseover被激活時,relatedTarget表示鼠標進入目標元素時,是從哪一個元素離開的,咱們能夠對relatedTarget的值進行判斷:若是值不是目標元素,也不是目標元素的子元素,就說明鼠標已移入目標元素;seo

(2) 當mouseout被激活時,relatedTarget表示鼠標離開目標元素時,進入了哪一個元素,咱們一樣能夠對relatedTarget的值進行判斷:若是值不是目標元素,也不是目標元素的子元素,就說明鼠標已移出目標元素;

五. 實例

// HTML:
<ul id="J_List">
<li><a href="#">item1</a></li>
<li><a href="#">item2</a></li>
<li><a href="#">item3</a></li>
</ul>
// JS(基於YUI):<script type="text/javascript">   var Y = YAHOO.util,        Dom = Y.Dom,        Event = Y.Event;   // 獲取全部的li   var oList = Dom.get('J_List');   Event.on(oList, 'mouseover', function(e) {        var rt = Event.getRelatedTarget(e),             curElem = this;        // 若是rt不是curElem且不是curElem的子元素, 則就是mouse enter的狀況        if (rt !== curElem && !Dom.isAncestor(curElem, rt)) {             console.log('enter: ' + curElem.id);        }    });    Event.on(oList, 'mouseout', function(e) {         var rt = Event.getRelatedTarget(e),              curElem = this;         // 若是rt不是curElem且不是curElem的子元素, 則就是mouse leave的狀況         if (rt !== curElem && !Dom.isAncestor(curElem, rt)) {              console.log('leave: ' + curElem.id);         }    });</script>
相關文章
相關標籤/搜索