阅读 122

事件委托

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父结点上,由父节点的监听函数统一处理多个子元素的事件,这种方法叫事件委托。

事件委托的优点

  1. 减少内存消耗,提高性能

    对于如下代码

    <div class='buttons'>     <button>按钮1</button>     <button>按钮2</button>     <button>按钮3</button>     <button>按钮4</button> </div> 复制代码

    现需要在点击每个 button 时响应一个事件,如果给每个 button 都绑定一个函数,那么会消耗较多的内存。借助事件委托,只需要将监听函数定义在父元素 div 上,这样不管点击的是哪一个 button 标签,遵循冒泡的传递机制,都会响应事件。

  2. 可以监听动态元素

    很多时候,用户的一些操作会增删某个子元素,如果一开始给每个子元素绑定事件,那么在子元素发生变化是,就需要给新增元素绑定事件,给要删除的元素解绑事件,使用事件委托就会省去很多类似的麻烦。

事件委托的实现:

<div id='container'>  <button>按钮1</button>  <button>按钮2</button>  <button>按钮3</button>  <button>按钮4</button> </div> <script>  container.addEventListener('click', function(e){            //把目标元素赋值给t      let t = e.target             //判断是否匹配目标元素      if (t.matchs('button')) {          console.log('这是:' + t.textContent);      }  }; </script> 复制代码

这样点击 button 时会触发事件,打印出相应元素的文本内容。

基于此,可以封装一个事件委托函数

on('click', '#container', 'button', ()=>{     console.log('这是:' + t.textContent) }) function on(eventType, element, selector, fn) {     //判断是不是 Element      //如果传进来的是选择器,不是 Element 本身,就先变成 Element     //因为只有 Element 才能监听事件     if (!(element instanceof Element)) {         element = element.querySelector(element)     }     parentElement.addEventListener(eventType, (e)=>{         let target = e.target         if (target.matches(selector)) {             fn(e)         }     }) } 复制代码

当被点击的元素有多个层级时,则需要递归判断其祖先元素,直到找到监听的元素(注意限定判断范围)

on('click', '#contaniner', 'button', ()=>{     console.log('用户点击了li') }) function on(eventType, element, selector, fn) {     if (!(element instanceof Element)) {         element = document.querySelector(element)     }       element.addEventListener(eventType, (e)=>{         let el = e.target                  // 如果匹配到了selector就跳出循环         while(!el.matches(selector)){             if (el === element){                                  //已经找到了父元素,说明还没找到,就设置为null                 el = null                 break             }             el = el.parentNode         }               // 找到了el, 就调用函数         el && fn.call(el, e, el)             }) }


作者:易安_Ian
链接:https://juejin.cn/post/7022458263920705544

文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐