3.阻止冒泡与默认行为

查看飞书原文 ↗2,464 字符
在事件处理中,有时我们需要更精细地控制事件的行为。浏览器为我们提供了两个强大的工具:event.stopPropagation() 和 event.preventDefault(),它们分别用于控制事件的“传播”和“默认动作”。​
​
1. event.stopPropagation():截断事件的传播之路​
​
•
功能: 阻止事件从当前元素继续向上冒泡到父元素。​
•
核心场景: 当一个元素和它的父元素都绑定了相同的事件(如 click)时,我们可能只希望触发子元素的事件,而不希望“打扰”到父元素。​
•
比喻: 事件冒泡就像水中的涟漪,会一圈圈向外扩散。event.stopPropagation() 就像在涟漪扩散的路径上立刻放置了一道屏障,让涟漪无法继续向外传播。​
​
示例:卡片内的关闭按钮​
​
想象一个可以点击的卡片(div.card),点击后会跳转到详情页。卡片右上角有一个关闭按钮(span.close),点击它应该只关闭卡片,而不是跳转页面。​
​
HTML 结构:​
<div class="card">
  我是一张卡片,点击我会跳转...
  <span class="close">×</span>
</div>
​
JavaScript 实现:​
​
const card = document.querySelector('.card');
const closeBtn = document.querySelector('.close');

// 父元素:卡片的点击事件
card.addEventListener('click', () => {
  console.log('触发了卡片的点击事件,准备跳转页面!');
  // window.location.href = '/details';
});

// 子元素:关闭按钮的点击事件
closeBtn.addEventListener('click', (event) => {
  // 关键:阻止事件冒泡到父元素 card 上
  event.stopPropagation();

  console.log('触发了关闭按钮的点击事件,卡片已关闭。');
  card.style.display = 'none';
});
​
运行效果:​
​
•
如果点击卡片的空白区域: 控制台会输出 触发了卡片的点击事件,准备跳转页面!。​
•
如果点击 × 关闭按钮: 因为调用了 event.stopPropagation(),事件在 <span> 处就被截断了,不会再冒泡到 <div class="card">。因此,控制台只会输出 触发了关闭按钮的点击事件,卡片已关闭。,而不会触发卡片的跳转行为。​
​
​
​
​
2. event.preventDefault():取消浏览器默认行为的“常规操作”​
​
•
功能: 取消与特定事件关联的浏览器默认行为。​
•
核心场景: 阻止链接的默认跳转行为、阻止表单的默认提交行为等。​
示例1:阻止链接跳转​
​
我们想点击一个链接后,不跳转页面,而是弹出一个提示框。​
​
HTML 结构:​
<a href="https://google.com" id="myLink">访问谷歌</a>​
​
JavaScript 实现:​
const myLink = document.querySelector('#myLink');

myLink.addEventListener('click', (event) => {
  // 关键:阻止 <a> 标签的默认跳转行为
  event.preventDefault();

  alert('链接的默认跳转行为已被阻止!');
});
运行效果: 点击“访问谷歌”链接后,浏览器不会跳转到 Google,而是会弹出一个 alert 提示框。​
​
示例2:自定义表单提交​
​
在现代前端开发中,我们通常不希望表单提交导致页面刷新,而是希望通过 AJAX(如 fetch)在后台异步提交数据。​
​
HTML 结构:​
<form id="myForm">
  <input type="text" id="username" placeholder="输入用户名">
  <button type="submit">提交</button>
</form>
​
JavaScript 实现:​
const myForm = document.querySelector('#myForm');

myForm.addEventListener('submit', (event) => {
  // 关键:阻止 <form> 的默认提交(页面刷新)行为
  event.preventDefault();

  const username = document.querySelector('#username').value;
  console.log(`表单的默认提交已被阻止。`);
  console.log(`正在通过 AJAX 提交用户名:${username}`);

  // 在这里可以编写 fetch(...) 代码来异步发送数据
});
运行效果: 点击“提交”按钮后,页面不会刷新。你会在控制台看到输出的信息,这为我们执行异步数据交互提供了可能。​
总结对比​
​
​
方法​
​
​
作用​
​
​
控制什么?​
​
​
何时使用?​
​
​
event.stopPropagation()​
​
​
阻止传播​
​
​
控制事件在 DOM 树中的**垂直流动**(冒泡阶段)。​
​
​
防止父元素的事件处理器被触发。​
​
​
event.preventDefault()​
​
​
阻止默认动作​
​
​
控制浏览器对特定元素的**预设行为**。​
​
​
自定义链接点击、表单提交等行为。​
​
​
​

原文链接与附件索引