事件冒泡 & 事件捕获

55 阅读2分钟

《用得上的前端知识》系列 - 你我都很忙,能用100字说清楚,绝不写万字长文

基本概念

事件源:是指被触发dom事件的元素;

事件冒泡

“事件冒泡”是由微软公司提出的一种事件流模型,其事件流顺序为:从事件源往根节点(由内到外)进行事件传播。

<!-- 假设页面中有以下元素 -->
<div>
    <p>content</p>
</div>

<!-- 点击 p 元素后,按照事件冒泡模型,事件传播顺序为:p -> div -> body -> html -> document -->

事件捕获

“事件捕获”是由网景公司提出的一种事件流模型,其事件流顺序为:从根节点往事件源(由外到内)进行事件传播。

<!-- 假设页面中有以下元素 -->
<div>
    <p>content</p>
</div>

<!-- 点击 p 元素后,按照事件捕获模型,事件传播顺序为:document -> html -> body -> div -> p -->

addEventListener的第三个参数

为了平息网景和微软的战火,w3c 采用折中的方式,制定了事件流的统一标准:先捕获再冒泡

addEventListener 有三个参数:element.addEventListener(event, function, useCapture)

  • 第一个参数(event)是需要绑定的事件;
  • 第二个参数(function)是触发事件后要执行的函数;
  • 第三个参数(useCapture)默认值是 false,表示在事件冒泡阶段调用事件处理函数;如果参数为 true,则表示在事件捕获阶段调用处理函数。

事件捕获 & 事件冒泡

当在一个元素上同时以“事件捕获”和“事件冒泡”的方式绑定事件时,事件的回调函数的触发顺序为:

  • 对于非target节点则先执行捕获再执行冒泡
  • 对于target节点则是先执行先注册的事件,无论冒泡还是捕获

注:target节点为被点击的DOM节点。

事件冒泡与事件捕获的应用

最经典的应用就是:事件代理。

比如:

  • 为“无限下拉列表”添加事件绑定;
  • 为列表中的 10000 个元素绑定 click 事件。

冒泡还是捕获?

对于事件代理来说,在事件捕获或者事件冒泡阶段执行回调函数并没有明显的优劣之分,但是由于事件冒泡的事件流模型被所有主流的浏览器兼容,从兼容性角度来说还是建议使用事件冒泡模型。

阻止事件冒泡和默认行为

阻止事件冒泡/事件捕获的方法

  • event.stopPropagation(); //W3C标准
  • event.cancelBubble = bool; //这里主要指IE低版本IE9以下版本,因为IE9也实现了W3C标准

阻止默认行为

  • event.preventDefault(); //W3C标准
  • window.event.returnValue = false; //IE9 以下的实现

参考资料