JavaScript DOM事件处理-事件捕获和事件冒泡

 2015年10月06日    984     声明


在浏览器端JavaScript事件驱动的异步编程模式下,如果JavaScript关注特定类型的事件,那么就可以为事件注册事件处理程序。在DOM文档中,当事件发生时会逐级向上传递,并最终传递给文档树。如果DOM元素注册过事件处理程序,当事件传递到对应位置就会被事件处理程序(注册的函数)所处理。这种事件传播机制叫做事件“冒泡”。


1. 什么是事件冒泡

当一个DOM元素上的事件被触发的时候(如:按钮点击事件),同样的事件将会在那个元素的所有父元素中被触发,从这个事件会从原始元素开始一直传递到DOM树的最上层,这一过程被称为事件冒泡


2. 什么是事件捕获

浏览器获取事件(如:按钮点击事件)是从DOM的最项层开始的,事件发生后会从DOM的根开始向下传递,直到目标元素,目标元素的所有父先元素都会被依次遍历,浏览器获取事件的过程被称为事件捕获


事件捕获发生在事件冒泡之前。 事件捕获是从上级元素到下级元素,即:从最不精确的对象(document)开始触发,然后到最精确的目标元素的顺序触发。事件冒泡是从下级元素到上级元素,即:从最特定的事件目标到最不特定的事件目标(document)的顺序触发。

3. 浏览器对事件的处理过程

DOM0级事件中,事件处理只有事件冒泡的过程,在IE8及其早期版本中只支持DOM0级事件。而W2C规范中的DOM2级事件规范中,规定了事件处理分为三个阶段:

  • 1. 事件捕获阶段
  • 2. 事件目标阶段
  • 3. 事件冒泡阶段

DOM2中添加了一个添加事件处理程序的函数:target.addEventListener(ev, fn, useCapture),通过这个方法你可以通过useCapture参数设置是在事件捕获还是在事件冒泡阶段处理事件。

JavaScript DOM事件捕获和事件冒泡


4. 不需要冒泡的事件及事件停止冒泡

4.1 不需要冒泡的事

当事件目标是Document对象之外的对象,如:Window等对象时,事件不会冒泡,浏览器会调用对象上相应的事件处理程序响应事件。别外,有些事件,如:blur、focus、load、unload等事件,不会像其它事件一样冒泡,因为这些事件的捕获方式与冒泡事件不一样。


4.2 事件停止冒泡与阻止默认事件

当事件冒泡到处理程序后,可能需要停止继续冒泡或阻止默认事件。在DOM2中增加了stopPropagation()方法,该方法会阻止事件的继续传播,在IE8及早期版本中可以使用cancelBubble = true来停止冒泡。

if(event.stopPropagation) {
     event.stopPropagation();
} else {
    window.event.cancelBubble = true;
}

在事件发生过程中,有时需要阻止默认事件的发生,使用event对象的defaultPrevented()方法可以阻止默认事件,在IE8及早期版本中可以使用returnValue阻止默认事件。

if(event.defaultPrevented) {
     event.defaultPrevented();
} else {
    window.event.returnValue = false;
}