全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 6 分钟 ✍️ juanwangdev

事件委托

事件委托(事件代理)是将事件监听器绑定在父元素上,利用事件冒泡统一处理子元素事件的技术。

核心原理

利用事件冒泡:子元素事件会冒泡到父元素,通过 event.target 判断具体触发元素。

JavaScript
// 不使用事件委托:每个li都绑定事件
document.querySelectorAll('li').forEach(li => {
  li.addEventListener('click', handler);
});

// 使用事件委托:只在父元素绑定一个事件
ul.addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    console.log(e.target.textContent);
  }
});

基本用法

判断目标元素

JavaScript
ul.addEventListener('click', (e) => {
  // 判断点击的是li元素
  if (e.target.tagName === 'LI') {
    e.target.classList.toggle('active');
  }
});

matches方法

使用CSS选择器匹配:

JavaScript
ul.addEventListener('click', (e) => {
  if (e.target.matches('.item')) {
    console.log('点击了item');
  }
});

closest方法

处理嵌套结构:

JavaScript
ul.addEventListener('click', (e) => {
  const li = e.target.closest('li');
  if (li && ul.contains(li)) {
    console.log(li.textContent);
  }
});

适用场景

动态添加的元素

JavaScript
// 新添加的li自动拥有点击事件
ul.addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    console.log(e.target.textContent);
  }
});

// 动态添加
const li = document.createElement('li');
ul.appendChild(li);  // 无需单独绑定事件

大量相似元素

JavaScript
// 1000个单元格,只绑定一个事件
table.addEventListener('click', (e) => {
  if (e.target.tagName === 'TD') {
    console.log('单元格被点击');
  }
});

统一管理事件

JavaScript
// 通过data属性区分不同操作
list.addEventListener('click', (e) => {
  const action = e.target.dataset.action;
  switch(action) {
    case 'edit':
      editItem(e.target);
      break;
    case 'delete':
      deleteItem(e.target);
      break;
  }
});

优缺点对比

优点缺点
减少内存占用需要判断target
动态元素自动绑定不支持不冒泡事件
代码简洁层级嵌套判断复杂

注意:focusblur 等事件不冒泡,需用 focusinfocusout 替代。

完整示例

JavaScript
// HTML结构
// <ul id="list">
//   <li data-id="1">项目1 <button data-action="delete">删除</button></li>
// </ul>

document.getElementById('list').addEventListener('click', (e) => {
  const action = e.target.dataset.action;

  if (action === 'delete') {
    const li = e.target.closest('li');
    li.remove();
    return;
  }

  const li = e.target.closest('li');
  if (li) {
    console.log('选中:', li.dataset.id);
  }
});

要点总结

  1. 事件委托利用事件冒泡,在父元素统一处理
  2. 通过 e.targete.target.closest() 判断目标元素
  3. 动态添加的元素无需重新绑定事件
  4. 大量元素时显著减少内存占用
  5. 不冒泡事件(如focus/blur)无法使用委托

📝 发现内容有误?点击此处直接编辑

← 上一篇 事件冒泡与捕获
下一篇 → 事件对象
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库