《用得上的前端知识》系列 - 你我都很忙,能用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 以下的实现