事件的三个阶段

mac2025-07-13  5

事件的三个阶段

事件触发时候会经历三个阶段:①事件捕获阶段 ②执行阶段(执行当前元素的注册事件) ③事件冒泡阶段。本节通过一个示例,对三个阶段加以总结 引入: addEventListener(type,listener,userCapture)

type:事件名称 click mouseover mouseoutlistener:事件注册函数userCapture:可选,bool类型,默认为false 示例: 示例描述:页面中嵌套三个盒子,box1,box2,box3(从外到内,依次是红色,绿色,蓝色),给三个盒子都注册点击事件,输出三个盒子的id,点击蓝色盒子,结果如下: 页面效果:

点击蓝色盒子,控制台输出结果: 点击红色盒子,控制台输出结果:

分析: 在上述代码中,给addEventListener的userCapture属性赋值为true,此时事件阶段是事件捕获阶段。 当addEventListener的userCapture属性赋值为false时,此时事件阶段是事件冒泡阶段。 当属性为false时候,从里往外执行,这种执行效果称为事件冒泡,就像一个气泡从水里最深处往外冒一样。事件冒泡从里面往外面泡,从最小的元素一直往外传递,传递到最外层的元素。此时,在事件执行过程中,先执行事件捕获,box1–>box2–>box3,执行完box3的点击事件后,再从里向外执行,box3–>box2–>box1. 在代码中,只能处理事件捕获或者事件冒泡其中的一个阶段,其实这三个阶段都会发生,当点击box3时候,事件捕获也发生了,只不过没办法通过代码进行干预。 当在上述代码中,给addEventListener的userCapture属性赋值为true,选执行最外层的box1,再执行box2,box3,这种从外向里的过程是事件捕获。 onclik/attachEvent都不能设置冒泡或者捕获阶段,他们都是事件冒泡,我们最需要重视的也是事件冒泡 代码如下:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件冒泡</title> <style type="text/css"> #box1{ width: 300px; height: 300px; background-color: red; } #box2{ width: 200px; height: 200px; background-color: green; } #box3{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <div id="box1"> <div id="box2"> <div id="box3"></div> </div> </div> <!-- 插入JS代码 --> <script type="text/javascript"> //获取所有的box var box1=document.getElementById('box1'); var box2=document.getElementById('box2'); var box3=document.getElementById('box3'); //给三个box注册点击事件 建议使用数组 var boxs=[box1,box2,box3]; for(var i=0;i<boxs.length;i++){ boxs[i].addEventListener('click',outPut,true); } //点击事件函数 function outPut(){ console.log(this.id); } </script> </body> </html>

事件冒泡的作用------事件委托

事件冒泡的作用通过事件委托来体现,也是通过一个示例,来了解事件委托。 需求:点击页面中各个项,点击哪个项,哪个项背景高亮显示。 页面效果如下:

在网页中,有一个ul标签,ul中包括6个标签,要实现上面效果,以前的做法是首先找到ul,然后找到ul里面所有的li,遍历所有的li标签,给它们逐个注册点击事件。 现在,有了事件冒泡,就不用给每一个li注册点击事件了。因为冒泡事件的作用,点击li元素的时候,点击事件可以传送到父元素上来,即本来该li做的事情,交给ul去做,再者就是事件委托。 代码如下:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件冒泡的作用----事件委托</title> <!-- 点击li标签内容,让其背景高亮显示 --> </head> <body> <ul id="ul"> <li>夏侯惇</li> <li>夏侯渊</li> <li>典韦</li> <li>许褚</li> <li>徐晃</li> <li>张辽</li> </ul> <!-- 插入JS代码 --> <script type="text/javascript"> //获取ul标签 var ul=document.getElementById('ul'); //因为li是ul内部的元素,根据事件冒泡原理,从内到外执行,点击最里面的元素,最终会由内向外执行 //所有的注册事件,最终会执行到ul,在ul中的注册事件,根据传递过程中的传递数据,搭建事件委托,委托ul处理li的事件 ul.onclick=function(e){ //在点击的时候,清除所有的样式 var lis=this.children; for(var i=0;i<lis.length;i++){ lis[i].style.backgroundColor=''; } //e 事件对象 // e.target 真正点击的目标,是真正触发事件的对象 e.target.style.backgroundColor='red'; } </script> </body> </html>

代码分析: 在事件处理函数中,可以传递一个参数e,这个参数我们叫做事件对象,也叫事件参数。事件对象e是系统传递过去,事件函数也是系统调用的。系统调用事件函数的时候,会给事件函数传递一个参数,传递的参数具有具体值,可以在事件函数执行时获取e中携带的值。 e:事件参数,也叫事件对象,可以写作a,习惯上写成e e.target 真正触发事件的对象 总结:事件委托简化了以前给所有的li注册事件的一个过程,只需要给这些元素的父元素注册事件就好了。

事件对象e

通过事件对象e,可以获得事件发生时一些和事件相关的数据(事件的一些属性)。 例如:<input type='button' id='btn' value='按钮'></input>

给按钮注册点击事件,但是当给按钮注册完点击事件后,如何获取事件对象那? var btn=document.getElementById('btn'); btn.onclick=function(e){}

DOM标准中,是给事件处理函数一个参数,就是给function一个参数e,e就是事件对象。这是标准方式。 在老版本的IE中获取事件对象的方式是 window.event 所有事件对象e在浏览器中存在兼容性问题, 处理方式:让e始终是事件对象,如下: e = e || window.event;

获取了事件对象e后,我们想知道e里面有什么,或者说e怎么用呢?

获取事件阶段 console.log(e.eventPhase) 获取事件阶段 1事件捕获阶段 2 事件目标阶段 3事件冒泡阶段

获取事件真正出发的对象(事件源) e.target ,但是e.target存在浏览器兼容性问题,老版本IE中,是srcElement,解决办法如下: target = e.target || e.srcElemnet

获取事件处理函数所在的对象 e.currentTargert e.currentTargert作用与this一样,所有可以用this代替 如果没有事件冒泡, e.currentTargert与e.target都是一样的。 通过示例代码具体分析,代码如下:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件对象</title> <style type="text/css"> #box1{ width: 300px; height: 300px; background-color: red; } #box2{ width: 200px; height: 200px; background-color: green; } #box3{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <div id="box1"> <div id="box2"> <div id="box3"></div> </div> </div> <!-- 插入JS代码 --> <script type="text/javascript"> // 获取三个盒子id,并给三个盒子注册点击事件 var box1=document.getElementById('box1'); var box2=document.getElementById('box2'); var box3=document.getElementById('box3'); var boxs=[box1,box2,box3]; for(var i=0;i<boxs.length;i++){ boxs[i].onclick=function(e){ console.log(this.id);//点击输出各个盒子的id console.log(e.target);//输出触发点击事件的盒子 console.log(e.currentTarget);//输出点击事件所在的对象 } } </script> </body> </html>

实际效果: 原始图: 依次点击红->绿->蓝色盒子结果图: 结果依次为:box1->box2、box1->box3、box2、box1

上述点击蓝色结果分析: 事件最终反馈冒泡阶段,即从内向外执行,依照box3---->box2---->box1顺序执行点击函数 box3: id:box3,触发函数对象:<div id='box3'></div> 事件所在对象:<div id='box3'></div> box2: id:box2,触发函数对象:<div id='box3'></div> 事件所在对象:<div id='box2'></div> box1: id:box1,触发函数对象:<div id='box3'></div> 事件所在对象:<div id='box1'></div> 上述点击绿色结果分析: 上述结果分析:事件最终反馈冒泡阶段,即从内向外执行,box2---->box1顺序执行点击函数 box2: id:box2,触发函数对象:<div id='box2'></div> 事件所在对象:<div id='box2'></div> box1: id:box1,触发函数对象:<div id='box2'></div> 事件所在对象:<div id='box1'></div> 4. 获取事件处理函数名称 e.type 作用:对于一个元素,可能有click mouseover mouseout事件等,如果一个一个定义,比较耗费内存,可以只定义一个函数,让click mouseover mouseout指向该函数,在函数中使用switch-case加以判别,具体如下代码所示:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件对象</title> <style type="text/css"> #box1{ width: 100px; height: 100px; background-color: red; } </style> </head> <body> <div id="box1"> </div> <!-- 插入JS代码 --> <script type="text/javascript"> function fn(e){ switch(e.type){ case 'click': console.log('这是一个点击事件'); break; case 'mouseout': console.log('这是鼠标移出事件'); break; case 'mouseover': console.log('这是鼠标悬浮事件'); } } // 获取三个盒子id,并给三个盒子注册点击事件 var box1=document.getElementById('box1'); box1.onclick=fn; box1.onmouseout=fn; box1.onmouseover=fn; </script> </body> </html>
最新回复(0)