前端-javascript-事件流机制,事件委托,事件代理详解

事件委托或者事件冒泡其实都是基于js的事件流机制产生的。在说时间委托和事件代理之前,我们先来了解下事件流,搞懂事件流,也就知道了事件委托,事件代理是怎么回事了,下面上个图(摘自https://www.cnblogs.com/wxf-h/)

事件流图如下:
事件触发流程图
由图看,当一个事件被触发时发生了什么:
1.整个事件流程是从window开始又回到window的过程。
2.整个事件流分为三个阶段,1.从window开始向下捕获(1~5)。2.确定事件目标元素(5,6)。3.向上冒泡过程(7-10)。

这也就引用出来,事件冒泡和捕获的原理,因为事件流是从window开始,再回到window。所以会产生捕获和冒泡。
下面写一段代码解释下:

<body>
  <div class="a">
    a
    <div class="b">b</div>
  </div>
</body>
  <script type="text/javascript">
    var a=document.getElementsByClassName("a")[0];
    var b=document.getElementsByClassName("b")[0];
    a.oclick=function(){       //此处绑定两个a的**Dom0**级事件
      console.log("a");
    }
    a.onclick=function(){
      console.log("a2");
    }
    b.onclick=function(){
      console.log("b");
    }
  </script>

此时点击b元素,运行结果输出:
b
a2
上面的例子是 ”Dom0“ 级事件,在Dom0级事件中一个元素相同的事件只能绑定一次如(onclick),并且绑定的是最后绑定的那个事件,这个有点像jquery中的html方法一样,后面的会覆盖掉前面的内容一样。在Dom0级事件里只有事件冒泡没有事件捕获
此处流程就是首先进行从window捕获 ,捕获到事件元素触发事件,在冒泡触发到window。这就是事件触发的流程,由此可以看出,事件代理是怎么形成的了。

在Dom2级事件里支持事件冒泡和事件捕获

a.addEventListener("click",function(){
      console.log("a");
    },false);
    a.addEventListener("click",function(){
      console.log("a-2");
    },false);
    b.addEventListener("click",function(){
      console.log("b");
    },false);

执行结果
b
a
a-2

这里是发生了事件冒泡,点击b,先执行了b后输出了a和a-2,同时可以看出Dom2级事件是支持添加同名事件的按照先后顺序执行。addEventListener是Dom2里添加事件监听的写法可以接受三个参数,第一个参数是事件名称,第二个是事件处理函数,第三个参数是布尔值true是设置事件捕获,false是设置事件冒泡,默认情况下是false。IE里面添加监听事件是attachEvent但是IE不支持事件捕获,所以attachEvent只有前两个参数,不能设置true和false,同时事件名也要加上on。比如:addEventListener的单击事件是click,而attachEvent的单击事件是onclick。有添加监听事件就有移除监听事件,与addEventListener相对的是removeEventListener,与attachEvent相对应的是deatchEvent这两个写法与上面类似,需要注意的是移除事件时要同时删除事件名和对应的方法。为了解决和IE的兼容问题同城会将两种写法封装成一个函数进行调用,因为IE不支持事件捕获,所以尽量使用事件冒泡以解决兼容问题。

事件代理:
事件代理就是利用事件冒泡的原理来进行的,假如你的dom层级ul<li<a ,那么他点击a的时候,事件触发流程是a<li<ul,如果所有a的事件都是类似,可以最终绑定到最外层ul上同意代理。下面以ul<li为例。

        <ul id="a">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
     <script>
        var aLi = document.getElementById('a').children;
        for (var i=0;i<aLi.length;i++) { //传统方法是这么写的  循环绑定事件 
                    aLi[i].onclick= function() {
                        this.style.background = 'red';
                    }
                    
                }  
        //事件代理写法
        var ul=document.getElementById('a');
        ul.onclicl=function(ev){
           var ev = ev || window.event;
           var oLi = ev.srcElement || ev.target;
           oLi.style.background = 'red'
      }
    </script>
    也还可用事件代理进行绑定
  element.addEventListener(event, function, useCapture) 
 event : (必需)事件名,支持所有 DOM事件 。 
 function:(必需)指定要事件触发时执行的函数。 
 useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值