糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > JS事件的捕获和冒泡阶段

JS事件的捕获和冒泡阶段

时间:2019-12-27 21:09:56

相关推荐

JS事件的捕获和冒泡阶段

JS事件的捕获和冒泡阶段

这里介绍两个事件模型:IE事件模型与DOM事件模型

IE内核浏览器的事件模型是冒泡型事件(没有捕获事件过程),事件句柄的触发顺序是从ChildNode到ParentNode。

<div id="ancestor"> <button id="child"> child</button> <button id="child2"> child2</button> </div>

以上的HTML代码在IE内核下,事件是这样传播的:

1、Button#child;

2、div#ancestor;

3、Body;

4、Document

DOM标准的浏览器事件是:捕获事件和冒泡事件。

捕获事件过程

1、Window

2、Document

3、Body

4、Div#ancestor

5、Button#child

冒泡事件过程

6、Div#ancestor

7、Body

8、Document

9、Window

当开发者在一个元素上注册了事件后,这个事件的响应顺序是从window(最顶层)开始一级一级的向下传播,然后到了该元素后事件捕获过程结束,事件开如冒泡,一级一级向父层元素冒泡(请注意第6步)。

当然,开发者可以很轻松的决定DOM标准的浏览器中的事件需要在哪个传播过程触发。

事件的注册机制

DOM标准的浏览器事件注册方法是通过addEventListener方法注册,而IE内核的浏览器则是通过attachEvent方法注册。

addEventListener

addEventListener方法带有三个参数,分别是:eventType、handler、useCapture。

a. eventType不带有on字符串;

b. handler参数是一个事件句柄,这个函数或方法带有一个事件对象参数;

c. useCapture参数决定了事件句柄触发在哪种事件传播阶段,如果useCapture为true则为捕获阶段,反之则为冒泡阶段。

// html文件<div id="ancestor"> <button id="child"> child</button> <button id="child2"> child2</button> </div>

// js代码let ancestorHandler = function (e){console.log("div");}let childHandler = function (e){console.log("button");};document.querySelector('#ancestor').addEventListener('click',ancestorHandler,false);//注意第三个参数 ,注册了一个在冒泡阶段触发的事件句柄document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数 ,注册了一个在捕获阶段的事件句柄

输出结果:

"button""div"

当用户在这个DIV元素上点击时,事件的执行顺序是childHandler、ancestorHandler。

原因:按钮的事件是在捕获阶段触发的,也就是从上到下,而DIV的事件是注册在冒泡阶段,也就是点击了这个按钮开始从这个按钮的位置往上冒泡。

其中useCapture我们设置了true,我们选择在捕获阶段处理该handler。

其中useCapture我们设置了false,我们选择在冒泡阶段处理该handler。

我们来看一下事件的流程:

当用户点击DIV上的元素时,触发监听事件执行childHandler执行ancestorHandler

原因:按钮的事件是在捕获阶段触发的,也就是从上到下的顺序,而DIV的事件是注册在冒泡阶段,也就是在点击了这个按钮button之后,从这个位置往上冒泡。

阻止事件的冒泡:

DOM事件对象提供了stopPropagation方法用于阻止事件流。

var ancestorHandler = function (e){//...... }, childHandler = function (e){e.stopPropagation(); //...... };

以上代码在childHandler函数中添加了e.stopPropagation()代码片段,它将阻止事件流,事件流包括捕获阶段及冒泡阶段的事件流。

再修改上面的代码如下:

let ancestorHandler = function (e){console.log("div");}let childHandler = function (e){console.log("button");};document.querySelector('#ancestor').addEventListener('click',ancestorHandler,true);//注意第三个参数 document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数

输出结果:

// 点击child"div""button"// 点击child2"div"

分析一下上面的代码

点击child按钮

1.当用户点击div内的child按钮元素时,将会依次触发ancestorHandler、childHandler函数

2.原因是我们将div#ancestor的事件注册到捕获阶段了,也就是从上到下。

3.用户点击div区域,仅仅先触发了ancestorHandler函数,因为事件流被阻止了

4.处理完ancestorHandler事件之后,再捕获到child点击事件,然后执行childHandler函数

点击child2按钮

1.当用户点击child按钮时,会触发点击div内的元素触发后的handler,也就是ancestorHandler函数

2.然后输出div

removeEventListener

删除监听事件处理函数的方法,主要是针对移除 addEventListener() 方法添加的监听事件。

removeEventListener同样带有三个参数,分别是:eventType、handler、useCapture,和addEventListener是同样的。

// 向 <div> 元素添加事件句柄document.getElementById("myDIV").addEventListener("mousemove", myFunction, false);// 移除 <div> 元素的事件句柄document.getElementById("myDIV").removeEventListener("mousemove", myFunction, false);

示例:

<!DOCTYPE html><html><head><meta charset="utf-8"><title>vincent</title><style>#myDIV {background-color: coral;border: 1px solid;padding: 50px;color: white;}</style></head><body><div id="myDIV"> div 元素添加了 onmousemove 事件句柄,在你移动鼠标时会显示随机数。<p>点击按钮移除 DIV 的事件句柄。</p><button onclick="removeHandler()" id="myBtn">点我</button></div><p id="demo"></p><script>document.getElementById("myDIV").addEventListener("mousemove", myFunction);function myFunction() {document.getElementById("demo").innerHTML = Math.random();}function removeHandler() {document.getElementById("myDIV").removeEventListener("mousemove", myFunction);}</script></body></html>

如果觉得《JS事件的捕获和冒泡阶段》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。