javascript事件捕获和冒泡

时间:2023-02-01 14:53:46

1、先看一下事件传播的两种形式:
DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有着相当大的影响。这两种事件流分别是捕获和冒泡。

(1)、事件捕获:
事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事件目标元素之间各个继承派生的元素所捕获,如果事件在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何元素以对事件做出处理;否则,事件会被接着传递给派生元素路径上的下一元素,直至目标元素。事件到达目标元素后,它会接着通过DOM节点再进行冒泡。

(2)、事件冒泡:
当事件在某一DOM元素被触发时,例如用户在客户名字节点上点击鼠标,事件将跟随着该节点继承自的各个父节点冒泡穿过整个的DOM节点层次,直到它遇到依附有该事件类型处理器的节点,此时,该事件是onclick事件。在冒泡过程中的任何时候都可以终止事件的冒泡,在遵从W3C标准的浏览器里可以通过调用事件对象上的stopPropagation()方法,在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播,事件将一直通过DOM冒泡直至到达文档根。

(3)、让我们更形象的了解事件的旅程:
先写一个文档树:

<div>
<span><a href="#">web开发</a></span>
<p><a href="#"></a></p>
</div>

如图:

javascript事件捕获和冒泡

举个列子:如果单击了锚文本a,那么div、span和a都会应该得到响应这次单击的机会(当然还有最顶层的document即window对象)。毕竟这几个元素都处于用户鼠标的指针之下,而且他们属于包含和被包含的关系!

所以允许多个元素响应单击事件的一种策略叫做“事件捕获”,事件首先会先交给最外层的元素,接着在交给更具体的元素。这个例子中,事件捕获会首先传递给div,然后是span,最后是a,如下面:

javascript事件捕获和冒泡

另一种响应的策略就是“事件冒泡”了,既当时间发生时,会首先发送给最具体的元素,在这个元素获得响应机会后,事件会向上冒泡到上一级元素,在我们的例子中,a首先会处理事件,然后依次顺序是span和div,
javascript事件捕获和冒泡

而在实际应用中,事件冒泡会给我们带来意想不到的烦恼,所以我们应该知道怎样在不需要事件冒泡的地方关闭它!
IE和FF都支持阻止事件冒泡方法:

_$("li1").onclick=function(ev){
var oEvent=ev||event;
alert("我是li!");
oEvent.cancelBubble = true;
};

FF具有的阻止事件冒泡方法是:

_$("li1").onclick=function(event){
alert("我是li!");
event.stopPropagation();
};

考虑到在IE下会报错,所以不适用。不过,如果你使用了框架Jquery,使用jquery注册的阻止方法event.stopPropagation(),.stopPropagation()方法,该方法可以完全阻止事件冒泡。

2、浏览器的event
IE的event和其他的标准DOM的Event是不一样的,不同的浏览器事件的冒泡机制也是有区别的:
IE:
window.event.cancelBubble = true;//停止冒泡
window.event.returnValue = false;//阻止事件的默认行为

Firefox:
event.preventDefault();// 取消事件的默认行为
event.stopPropagation(); // 阻止事件的传播

注:
1,不是所有的事件都能冒泡。以下事件不冒泡:blur、focus、load、unload。
2,阻止冒泡并不能阻止对象默认行为。
3,冒泡阻止,亲身体会才知道!