JavaScript篇:偷懒也有理!事件代理让我少写一半代码

大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

技术qq交流群:906392632

大家好,我是小杨,一个做了6年前端的老油条。今天想跟大家分享一个让我少写很多重复代码的技巧------事件代理。这个技术听起来高大上,其实原理特别简单,而且用起来真香!

一、为什么我需要事件代理?

记得我刚入行时,接到一个需求:做一个动态的待办事项列表,每个条目都要有删除按钮。我当时是这么写的:

javascript 复制代码
// 获取所有删除按钮
const deleteButtons = document.querySelectorAll('.delete-btn');

// 给每个按钮绑定点击事件
deleteButtons.forEach(button => {
  button.addEventListener('click', function() {
    我.todoList.removeItem(this.dataset.id);
  });
});

看起来没问题对吧?但是当列表动态添加新条目时,新加的删除按钮根本不会触发事件!于是我又写了:

javascript 复制代码
// 每次添加新条目都要重新绑定事件
function addNewItem(text) {
  const newItem = createItemElement(text);
  todoList.appendChild(newItem);
  
  // 重新绑定所有删除按钮
  bindDeleteEvents();
}

这样不仅代码冗余,性能也不好。直到我发现了事件代理这个"偷懒神器"!

二、事件代理的原理

事件代理(Event Delegation)利用了DOM事件的冒泡机制。简单来说,就是不在每个子元素上单独设置事件监听器,而是在它们的父元素上设置一个监听器。

当子元素触发事件时,事件会冒泡到父元素,父元素通过event.target就能知道是哪个子元素触发的。

三、用事件代理重构代码

用事件代理重写上面的例子:

javascript 复制代码
// 只需要在父元素上绑定一次
todoList.addEventListener('click', function(event) {
  // 检查点击的是否是删除按钮
  if (event.target.classList.contains('delete-btn')) {
    我.todoList.removeItem(event.target.dataset.id);
  }
});

看!代码量直接减半,而且无论后面添加多少新条目,删除功能都能正常工作,因为事件监听是在父元素上!

四、事件代理的三大优势

  1. 内存效率高:只需要一个事件监听器,而不是N个
  2. 动态元素无忧:新添加的子元素自动"继承"事件处理
  3. 代码简洁:减少重复代码,逻辑更集中

五、实际开发中的小技巧

  1. 精确判断目标元素 :可以用event.target.matches('selector')更灵活地匹配
javascript 复制代码
todoList.addEventListener('click', (e) => {
  if (e.target.matches('.delete-btn, .delete-btn *')) {
    // 处理删除逻辑
  }
});
  1. 性能优化 :对于超长列表,建议在父元素上设置passive: true
javascript 复制代码
todoList.addEventListener('touchstart', handler, { passive: true });
  1. 事件冒泡的坑 :如果子元素阻止了冒泡(stopPropagation),事件代理会失效

六、适合使用事件代理的场景

  • 列表/表格中的交互元素
  • 大量相似元素的相同操作
  • 动态添加的子元素
  • 需要性能优化的长列表

七、不适合的场景

  • 需要精确阻止冒泡的情况
  • 每个子元素需要完全不同的事件处理逻辑
  • 某些必须直接绑定的事件(如focus/blur)

结语

事件代理是我日常开发中最常用的技巧之一,它完美诠释了"少写代码多做事"的程序员哲学。下次当你发现自己在一遍遍写相似的事件绑定代码时,不妨试试事件代理,让你的代码更优雅、更高效!

相关推荐
用户6945295521702 分钟前
国内开源版“Manus”——AiPy实测:让你的工作生活走上“智动”化
前端·后端
帅夫帅夫4 分钟前
一文手撕call、apply、bind
前端·javascript·面试
J船长7 分钟前
APK战争 diffoscope
前端
小飞952719 分钟前
前端面试题总结-01
面试
鱼樱前端20 分钟前
重度Cursor用户 最强 Cursor Rules 和 Cursor 配置 mcp 以及最佳实践配置方式
前端
曼陀罗21 分钟前
Path<T> 、 keyof T 什么情况下用合适
前端
锈儿海老师27 分钟前
AST 工具大PK!Biome 的 GritQL 插件 vs. ast-grep,谁是你的菜?
前端·javascript·eslint
飞龙AI28 分钟前
鸿蒙Next实现瀑布流布局
前端
令狐寻欢29 分钟前
JavaScript中 的 Object.defineProperty 和 defineProperties
javascript
快起来别睡了30 分钟前
代理模式:送花风波
前端·javascript·架构