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)

结语

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

相关推荐
科普瑞传感仪器1 天前
从轴孔装配到屏幕贴合:六维力感知的机器人柔性对位应用详解
前端·javascript·数据库·人工智能·机器人·自动化·无人机
n***F8751 天前
SpringMVC 请求参数接收
前端·javascript·算法
wordbaby1 天前
搞不懂 px、dpi 和 dp?看这一篇就够了:图解 RN 屏幕适配逻辑
前端
程序员爱钓鱼1 天前
使用 Node.js 批量导入多语言标签到 Strapi
前端·node.js·trae
鱼樱前端1 天前
uni-app开发app之前提须知(IOS/安卓)
前端·uni-app
V***u4531 天前
【学术会议论文投稿】Spring Boot实战:零基础打造你的Web应用新纪元
前端·spring boot·后端
TechMasterPlus1 天前
VScode如何调试javascript文件
javascript·ide·vscode
i听风逝夜1 天前
Web 3D地球实时统计访问来源
前端·后端
iMonster1 天前
React 组件的组合模式之道 (Composition Pattern)
前端
呐呐呐呐呢1 天前
antd渐变色边框按钮
前端