在介绍之前,先说一下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吧~