美文网首页饥人谷技术博客
从onClick谈事件代理和了解事件传播机制

从onClick谈事件代理和了解事件传播机制

作者: YM雨蒙 | 来源:发表于2017-09-14 20:43 被阅读77次

    javasriptdelegate这个词经常出现,看字面的意思,代理、委托。

    要搞懂事件代理,我们先来看看什么是代理,相信我们生活中现在还有朋友在做微商的,而微商的产品就是一级一级代理,下家找上家拿货这样子,你卖了东西从上家拿货,这个过程相当于你也有了货

    我们怎么从字面上来了解事件的代理呢?慢慢来,我们先来看一个需求,有这样一个列表,当我们每次点击的时候,就在控制台打印列表里的内容

    作为一名新手,我经常这样绑定onclick事件

    我会循环每一个li当我点击一个在控制台显示打印结果,全部绑定click事件,于是,我的代码是这样的

     <ul class="ct">
        <li>我是一号</li>
        <li>我是二号</li>
        <li>我是三号</li>
        <li>我是四号</li>
        <li>我是五号</li>
      </ul>
      <button type = "button" id="btn">增加</button>
    
    var ul = document.querySelector(".ct")
    for(var i=0;i<ul.children.length;i++){
      ul.children[i].onclick = function(){
        console.log(this.innerText)
      } 
    }
    
    代码没有问题

    我觉得这样写的挺好的,可是有人说这样会耗费性能,那我就不管了,可是当我改了一下需求,我发现这个代码用的没那么舒服了

    我在代码中通过js加入新的li,当我点击新的li时,控制台没有打印我的代码?怎么回事?

    我加入了几这样的代码

    var btn =document.querySelector("#btn")
    var i =6
    btn.addEventListener("click",function(){
      var node = document.createElement("li")
      node.innerText = "我是" + i++ + "号"
      ul.appendChild(node)
    })
    
    后面增加的li没有在控制台打印

    这是为什么?因为原有的li跟我后面生成的li根本不是同时发生的,在创建新的li元素之前,已经给存在的li加事件了,好吧,那我怎么修改呢?难道要重新循环遍历,太麻烦了,

    有人告诉我可以用代理,代理是什么,看了文章,好吧,修改一下代码

    ul.addEventListener("click",function(e){
     // 检查事件源e.targe是否为Li
      if(e.target.nodeName.toLowerCase() == 'li'){
        console.log(e.target.innerText)
      }
    })
    
    成功了
    新增新的点击li也会再控制台打印,解决了,于是耐心翻资料看了一下什么是事件代理:

    定义:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

    那什么是冒泡呢?

    • 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡

    回到我们本文的这个例子,看看改动后的代码,我把onlick事件绑定到了ul标签上面,而不是li标签。于是,当我点击任何一个li标签(不管是动态生成的还是之前就有的)是,这个事件就开始冒泡,寻找父元素。由于我这里给ul绑定了onlick,那么这时,ul会捕获冒泡上来的onclick事件。

    接着,如果,这个target刚刚好就是li标if(target.nodeName.toLowerCase() == 'li'),那么执行函数。

    简单介绍一下事件传播机制,主要介绍DOM2.0

    • DOM2.0模型将事件处理流程分为三个阶段:一、事件捕获阶段,二、事件目标阶段,三、事件起泡阶段。如图:
    事件传播
    • 事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

    • 事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

    • 事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

    相关文章

      网友评论

        本文标题:从onClick谈事件代理和了解事件传播机制

        本文链接:https://www.haomeiwen.com/subject/grxjsxtx.html