事件的三个阶段

事件的三个阶段

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

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

点击蓝色盒子,控制台输出结果:
在这里插入图片描述
点击红色盒子,控制台输出结果:

在这里插入图片描述
分析:
在上述代码中,给addEventListeneruserCapture属性赋值为true,此时事件阶段是事件捕获阶段。
addEventListeneruserCapture属性赋值为false时,此时事件阶段是事件冒泡阶段。
当属性为false时候,从里往外执行,这种执行效果称为事件冒泡,就像一个气泡从水里最深处往外冒一样。事件冒泡从里面往外面泡,从最小的元素一直往外传递,传递到最外层的元素。此时,在事件执行过程中,先执行事件捕获,box1–>box2–>box3,执行完box3的点击事件后,再从里向外执行,box3–>box2–>box1.
在代码中,只能处理事件捕获或者事件冒泡其中的一个阶段,其实这三个阶段都会发生,当点击box3时候,事件捕获也发生了,只不过没办法通过代码进行干预。
当在上述代码中,给addEventListeneruserCapture属性赋值为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怎么用呢?

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

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

  3. 获取事件处理函数所在的对象 e.currentTargert e.currentTargert作用与this一样,所有可以用this代替
    如果没有事件冒泡, e.currentTargerte.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>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值