JavaScript中事件委托的示例详解

 更新时间:2022年07月19日 08:14:52   作者:前端西瓜哥  
所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理。今天我们来认识一下JS中的事件委托

大家好,我是前端西瓜哥。今天我们来认识一下事件委托。

所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理。

事件流

事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。

事件流由两阶段组成:

  • 捕获事件
  • 冒泡事件

我们通常用 addEventListener 给元素添加事件:

document.querySelector('#card')addEventListener(
  'click',
  function (event) {
   console.log('div#card 冒泡点击', event);
 },
  false
);

第一个参数是事件名,第二个参数是事件响应函数,可以拿到当前的事件对象。

第三个参数是可选的,表示监听的是否为捕获阶段,false为冒泡阶段,也是默认值,true 为捕获阶段。我们常用的是冒泡阶段。

当我们点击元素时,就会执行这个函数。

假设我们的 DOM 结构如下:

<html>
  <head>
    <title>前端西瓜哥</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <div id="box-1">
        <div id="card">card</div>
      </div>
      <div id="box-2"></div>
    </div>
  </body>
</html>

现在我们点击 card 文字时,DOM 就会产生事件流。

事件流首先会进入 捕获阶段,从根节点往目标元素(div#card)移动,依次经过为:

  • window

  • document(文档根元素,在 HTML 中没有显式声明)
  • document.documentElement(<html>
  • document.body(<body>
  • ...
  • 目标元素 div#card

和调用事件对象的 event.composedPath() 方法拿到的 事件路径 类似。

window 看起来是个全局变量,但它也是可以绑定事件的,比如窗口大小改变的 resize 事件就只能绑定到 window 上,而不能绑定到 document 上。

然后再执行 冒泡阶段,然后反着再经过一遍这些节点。

图片

我们会根据事件流经过的顺序,依次执行这些节点上绑定的对应事件函数。

事件委托

假如我有一个好友列表,我希望点击 “聊天” 按钮,拿到对应用户 id,创建并进入到对应用户的聊天会话中。

<ul>
  <li>前端西瓜哥<button>聊天</button></li>
  <li>fe_watermelon<button>聊天</button></li>
  <!-- ... -->
  <li>老王<button>聊天</button></li>
</ul>

最直接的方式是给所有的 button 元素都绑定各自的事件。

节点少的时候还好,如果节点多达上千上万个,就需要声明相当多的事件函数,比较消耗内存。而且 如果列表经常发生动态变更,也会导致大量事件监听的移除和绑定

在这种情况下,事件委托就大有可为了。

事件委托正是利用事件流的冒泡特性,将本来要绑定到多个元素的事件函数,委托到了其祖先元素上

在上面这个例子中,我们可以将事件绑定到 ul 节点上,执行函数时,通过 event 对象拿到必要的信息,进行统一的操作。

document.querySelector('ul').addEventListener('click', (event) => {
  const target = event.target;
  const userId = target.getAttribute('data-user-id');
  if (userId) {
    joinChat(userId);
  }
});

通过 event.target 我们能获得这次事件流的目标节点,然后从该节点对象中提取出需要的信息。

在这里我们需要拿到用户 id,所以需要给 button 元素添加类似 data-user-id 的自定义属性,像这样子:

<ul>
  <li>前端西瓜哥<button data-user-id="5">聊天</button></li>
  <li>fe_watermelon<button data-user-id="99">聊天</button></li>
  <!-- ... -->
  <li>老王<button data-user-id="63">聊天</button></li>
</ul>

这样,不管 li 有多少,更新多频繁,我们只需要维护一个函数就够了。

结尾

事件委托,其实就是将原本应该绑定在子元素的的大量类似的事件监听函数,改为绑定到父元素或祖先元素上,委托祖先元素来处理。

不过在实际开发中,需要用到事件为委托的场景还是比较少,因为我们的列表通常不会太长。

到此这篇关于JavaScript中事件委托的示例详解的文章就介绍到这了,更多相关JavaScript事件委托内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用JavaScript实现连续滚动字幕效果的方法

    使用JavaScript实现连续滚动字幕效果的方法

    这篇文章主要介绍了使用JavaScript实现连续滚动字幕效果的方法,文中给出了浏览器端运行的示例脚本,需要的朋友可以参考下
    2015-07-07
  • JavaScript闭包的简单应用

    JavaScript闭包的简单应用

    这篇文章主要为大家详细介绍了JavaScript闭包的简单应用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • ES6的异步操作之promise用法和async函数的具体使用

    ES6的异步操作之promise用法和async函数的具体使用

    这篇文章主要介绍了ES6的异步操作之promise用法和async函数的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 基于js中document.cookie全面解析

    基于js中document.cookie全面解析

    下面小编就为大家带来一篇基于js中document.cookie全面解析。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 详解javascript replace高级用法

    详解javascript replace高级用法

    这篇文章主要介绍了详解javascript replace高级用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02
  • 原生js实现无缝轮播图效果

    原生js实现无缝轮播图效果

    本文主要分享了原生js实现无缝轮播图效果的示例代码,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • js中cookie的添加、取值、删除示例代码

    js中cookie的添加、取值、删除示例代码

    cookie的应用在网页中很常见,在本文为大家介绍下js中如何对cookie进行添加、取值、删除,感兴趣的朋友不要错过
    2013-10-10
  • javascript 数字格式化输出的实现代码

    javascript 数字格式化输出的实现代码

    这篇文章主要是对javascript中数字格式化输出的实现代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • 微信小程序实现轮播图效果

    微信小程序实现轮播图效果

    这篇文章主要为大家详细介绍了微信小程序实现轮播图效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • uniapp开发小程序的开发规范总结

    uniapp开发小程序的开发规范总结

    uni-app 是一个使用 vue.js 开发跨平台应用的前端框架,下面这篇文章主要给大家介绍了关于uniapp开发小程序的开发规范,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07

最新评论