瀏覽器中類比mouseenter omouseleave事件(解決onmouseover onmouseout重複調用)

來源:互聯網
上載者:User

標籤:

一. mouseenter和mouseleave何時被觸發

我們來看下官方解釋(mouseenter,mouseleave):

// 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的不同:

// 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支援它。。。

 


四. 如何類比?

原理:監聽目標元素的mouseover和mouseout事件,只當滑鼠移入目標元素時,才執行回呼函數,忽略子項目上啟用的mouseover和mouseout事件。我們通過事件對象的relatedTarget (ie瀏覽器為fromElement或toElement)屬性,來判斷滑鼠是移入/移出目標元素,還是在目標元素內移動:


(1) 當mouseover被啟用時,relatedTarget表示滑鼠進入目標元素時,是從哪個元素離開的,我們可以對relatedTarget的值進行判斷:如果值不是目標元素,也不是目標元素的子項目,就說明滑鼠已移入目標元素;


(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>

瀏覽器中類比mouseenter omouseleave事件(解決onmouseover onmouseout重複調用)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.