JavaScript 事件冒泡与事件捕获

事件冒泡和事件捕获是 JavaScript 中事件传播的两种机制,用于描述事件在 DOM 树中的传递顺序。

事件冒泡(Event Bubbling)

事件冒泡是指事件从目标元素向上传播到根元素(通常是 documentwindow)gt1.zzyol.com
。例如,点击一个按钮时,事件会从按钮依次向上传递到其父元素、祖父元素,直到根节点。

document.getElementById('child').addEventListener('click', function() {
  console.log('Child clicked');
});

document.getElementById('parent').addEventListener('click', function() {
  console.log('Parent clicked');
});

document.getElementById('grandparent').addEventListener('click', function() {
  console.log('Grandparent clicked');
});

点击 child 元素时,控制台输出顺序为:

Child clicked
Parent clicked
Grandparent clicked

事件捕获(Event Capturing)

事件捕获是事件从根元素向下传递到目标元素的过程。它与事件冒泡的顺序相反。要启用事件捕获,需要在 addEventListener 中将第三个参数设为 true

document.getElementById('child').addEventListener('click', function() {
  console.log('Child clicked (capturing)');
}, true);

document.getElementById('parent').addEventListener('click', function() {
  console.log('Parent clicked (capturing)');
}, true);

document.getElementById('grandparent').addEventListener('click', function() {
  console.log('Grandparent clicked (capturing)');
}, true);

点击 child 元素时,控制台输出顺序为:

Grandparent clicked (capturing)
Parent clicked (capturing)
Child clicked (capturing)

事件传播的完整流程

事件的完整传播流程分为三个阶段:

  1. 捕获阶段:事件从根元素向下传递到目标元素。
  2. 目标阶段:事件到达目标元素。
  3. 冒泡阶段:事件从目标元素向上冒泡到根元素。
document.getElementById('child').addEventListener('click', function() {
  console.log('Child clicked (target)');
});

document.getElementById('parent').addEventListener('click', function() {
  console.log('Parent clicked (bubbling)');
}, false); // 默认是冒泡阶段

document.getElementById('grandparent').addEventListener('click', function() {
  console.log('Grandparent clicked (capturing)');
}, true);

点击 child 元素时,控制台输出顺序为:

Grandparent clicked (capturing)
Child clicked (target)
Parent clicked (bubbling)

阻止事件传播

可以使用 event.stopPropagation() 阻止事件继续传播(无论是捕获还是冒泡056.kzzzhibo.cn)。

document.getElementById('child').addEventListener('click', function(event) {
  console.log('Child clicked');
  event.stopPropagation(); // 阻止事件向上冒泡
});

document.getElementById('parent').addEventListener('click', function() {
  console.log('Parent clicked'); // 不会执行
});

阻止默认行为

使用 event.preventDefault() 可以阻止事件的默认行为(例如链接跳转或表单提交)。

document.getElementById('link').addEventListener('click', function(event) {
  event.preventDefault(); // 阻止链接跳转
  console.log('Link clicked but not followed');
});

事件委托

事件委托是一种利用事件冒泡的优化技术,将事件监听器绑定到父元素,通过事件目标(event.target)cec.qyane.com判断具体触发事件的子元素。

document.getElementById('parent').addEventListener('click', function(event) {
  if (event.target.id === 'child1') {
    console.log('Child1 clicked');
  } else if (event.target.id === 'child2') {
    console.log('Child2 clicked');
  }
});

总结
  • 事件冒泡:事件从目标元素向上传播。
  • 事件捕获:事件从根元素向下传播。
  • 默认情况下,事件监听器在冒泡阶段触发。
  • 使用 event.stopPropagation() 可以阻止事件传播。
  • 事件委托可以减少事件监听器的数量,提高性能。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐