Timo

JavaScript 中的事件冒泡和事件捕获

事件和事件流

JavaScritp和HTML是通过事件来进行交互的。当浏览器中发生了一些特定的交互,比如点击、计时等,就会触发事件。我们可以通过监听器来监听事件,当事件发生时我们就可以执行相应的操作。

假如在页面中有一个按钮,如果我们点击了这个按钮,那么我们点击的不仅仅是这个按钮,这个按钮的所有的容器我们都发生了点击事件。而事件流就是描述事件在页面中传递的顺序。

在规范还统一的时候,事件流主要分为两类:一类是事件冒泡流(如IE),另一类是事件捕获流(如Netscape)。 后来DOM2级规范开始一种统一的方式来标准化DOM事件。现在IE9、Opera、Firefox、Safari和Chrome都实现了DOM2的事件流,但是IE8仍然是事件冒泡流。

事件冒泡

事件冒泡是从最具体的元素开始,一直往上传递,直到最不具体的元素为止。

例如有以下的代码:

<!DOCTYPE html>

Example
Click

如果我们点击了其中的<div>元素,那么这个事件的传递顺序为:

  1. <div>
  2. <body>
  3. <html>
  4. document

事件捕获

与事件冒泡相反,事件捕获从最不具体的元素开始,一直传递到事件的最具体元素。

同样,如果我们点击了上面<div>,事件的传递顺序为:

  1. document
  2. <html>
  3. <body>
  4. <div>

DOM事件流

在DOM事件流中,主要有三个阶段:事件捕获阶段处于目标阶段时间冒泡阶段

还是以上面的代码为例,整个事件的过程为:

  1. 在捕获阶段,事件从document传递到<body>就停止了。需要注意的是,捕获阶段不包括传递到<div>元素;
  2. 在处于目标阶段,即事件在<div>中发生;
  3. 在冒泡阶段,事件传回document。需要注意的是,<div>的事件处理也算作冒泡阶段。