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)

结语

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

相关推荐
菥菥爱嘻嘻4 分钟前
力扣面试150(44/150)
javascript·leetcode·面试
懋学的前端攻城狮15 分钟前
深入浅出Vue源码 - 剖析diff算法的核心实现
前端·vue.js·前端框架
JuneXcy17 分钟前
9.项目起步(3)
javascript·vue
小沙盒28 分钟前
使用js把txt的url列表转换成html列表
前端·javascript·html
超浪的晨38 分钟前
JavaWeb 进阶:Vue.js 与 Spring Boot 全栈开发实战(Java 开发者视角)
java·开发语言·前端·javascript·vue.js·html·个人开发
开开心心就好1 小时前
PDF转图片工具,一键转换高清无损
服务器·前端·智能手机·r语言·pdf·excel·batch
Java中文社群1 小时前
不要傻呵呵等金九银十了!
java·后端·面试
Java手札1 小时前
安装如下依赖(package.json 未包含):vueelement-plusecharts@element-plus/icons-vue
前端·javascript·vue.js
EndingCoder1 小时前
Three.js + AI:结合 Stable Diffusion 生成纹理贴图
开发语言·前端·javascript·人工智能·stable diffusion·ecmascript·three.js
haruma sen1 小时前
VUE前端
前端