標籤:
一. 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重複調用)