在介紹之前,先說一下JavaScript中的事件流概念。事件流描述的是從頁面中接受事件的順序。
一、事件冒泡(
Event Bubbling
)
IE
的事件流叫做事件冒泡,即事件開始時由最軀體的元素接收,然后逐級向上傳播到較為不具體的節點。
IE9
、
FF
、
Chrome
和
Safari
將事件一直冒泡到
<window>
對象。
二、
事件捕獲(
Event Capturing
)
事件捕獲的思想是不太具體的節點應該更早接收到事件,二最具體的節點應該最后接收到事件。
IE9
、
FF
、
Chrome
、
Opera
和
Safari
都支持這種事件流模型,“
DOM2
級事件”規范要求應該從
document
對象開始傳播,但是這些瀏覽器都是從
window
對象開始捕獲事件的。
三、DOM
事件流
“
DOM2
級事件”規范要求的事件流包括三個階段:事件捕獲階段、處於目標階段、事件冒泡階段。
IE8
及更早版本不支持事件流。“
DOM2
級事件”規范明確要求捕獲階段不會涉及事件目標,但是
IE9
、
FF
和
Opera
更高版本都會在捕獲階段觸發事件對象上的事件,所以,有兩個機會在目標對象上面操作事件。
對於jQuery中的事件模型,這篇文章講的非常詳細,基本思想我就不贅述了,各位可以點鏈接。
下面主要來說一下,上面說的文章中提到的事件冒泡的副作用,及其防止辦法。文中假設有如下結構的html代碼:
<div id="container"> <span> <a href="javascript:void(0)">Lorem ipsum dolor sit amet, consectetur adipisicing elit. A voluptas!</a> </span> </div>
對應的jQuery代碼如下:
$('#container').mouseout(function () {
$(this).hide("slow");
});
上述這樣的代碼,由於事件冒泡,
① 從a/span移出,但仍在div內部,div會hide;
② 從div移入a/span,div也會hide;
③ 當然,完全移出div,div也會hide。
按照文章中提出的一個方案,給div內部的每個元素都注冊相應事件,並使用.stopPropagation()方法阻止事件進一步傳播。結果如下:
① 移動方向:a/span -> div -> div之外,成功。
② 移動方向:div -> a/span,div消失,失敗。
所以說,該方案僅適合嚴格按照從內到外的方向移動,在內部隨意移動,就會失敗。總的來說,這不符合用戶上網習慣,限制太多了,實際中不能用。
文章提出在
jQuery中使用mouseenter和mouseleave避免冒泡的副作用,親測過可行。所以說,還是使用這兩種方法來代替mouseover和mouseout吧~
