美文网首页
原生 JS 实现事件委托

原生 JS 实现事件委托

作者: 饥人谷_rsrg | 来源:发表于2017-04-19 13:46 被阅读0次

    什么是事件委托

    事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。

    那么为什么需要事件委托呢?

    假设我们有一个ul ul里有两个li 我们需要给这两个li添加点击事件 那么我们可能会使用addEventListener 进行监听 添加点击事件 如果li有很多呢 给每一个li添加点击事件 那就会相当的麻烦 当然 你也许很有耐心 但是如果我们想给li动态的添加 那么新添加的li是不会被监听到的。

    那我们使用for循环,给每个li添加点击事件呢? 如果li数量很多 这样的话每一次循环都需要创建一个监听器并占用一定的内存,性能会变的很差,所以我们只需要给li的父元素添加一个监听器 就可以达到相同的效果,并且性能会有所提高。

    实现

       <ul>
            <li>一</li>
            <li>二</li>
            <li>三</li>
            <li>四</li>
        </ul>
    
    var ul=document.querySelector("ul");
    ul.addEventListener('click',function(){
      console.log('ok');
    })
    

    这样我们点击li时就会执行里面的代码 但是当我们点击ul内部但不是li的区域 还是会触发代码执行 所以我们需要判断点击的标签名是否正确再执行代码

    var ul=document.querySelector("ul");
    ul.addEventListener('click',function(e){
      if(e.target.nodeName==='LI'){
        console.log('ok');
      }
    })
    

    这样上面的问题就解决 但是这样就会引发另一个问题 当li存在子元素并且点击li里面的元素时,是不会执行代码的 所以我们需要再次修改

    var ul=document.querySelector("ul");
    ul.addEventListener('click',function(e){
      var ele=e.target;
      while(ele.nodeName!=='LI'){
        if(ele===ul){
          ele=null;
          break;
        }
        ele=ele.parentNode;
      }
      if(ele){
        console.log('ok');
      }else{
        console.log('no')
      }
    })
    

    将当前点击的元素存到ele变量中,判断ele是否是ul如果是则说明并没有点击li或者li内部的元素 所以将ele赋值为空并且退出循环,如果不是ul将ele赋值为ele的父元素再次循环进行判断。

    相关文章

      网友评论

          本文标题:原生 JS 实现事件委托

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