Skip to content

目录

在事件处理中,有时我们需要更精细地控制事件的行为。浏览器为我们提供了两个强大的工具:event.stopPropagation()event.preventDefault(),它们分别用于控制事件的"传播"和"默认动作"。

1. event.stopPropagation():截断事件的传播之路

  • 功能: 阻止事件从当前元素继续向上冒泡到父元素。
  • 核心场景: 当一个元素和它的父元素都绑定了相同的事件(如 click)时,我们可能只希望触发子元素的事件,而不希望"打扰"到父元素。
  • 比喻: 事件冒泡就像水中的涟漪,会一圈圈向外扩散。event.stopPropagation() 就像在涟漪扩散的路径上立刻放置了一道屏障,让涟漪无法继续向外传播。

示例:卡片内的关闭按钮

想象一个可以点击的卡片,点击后会跳转到详情页。卡片右上角有一个关闭按钮,点击它应该只关闭卡片,而不是跳转页面。

HTML 结构:

html
<div class="card">
  我是一张卡片,点击我会跳转...
  <span class="close">×</span>
</div>

JavaScript 实现:

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 结构:

html
<a href="https://google.com" id="myLink">访问谷歌</a>

JavaScript 实现:

javascript
const myLink = document.querySelector('#myLink')

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

  alert('链接的默认跳转行为已被阻止!')
})

运行效果: 点击"访问谷歌"链接后,浏览器不会跳转到 Google,而是会弹出一个 alert 提示框。

示例2:自定义表单提交

在现代前端开发中,我们通常不希望表单提交导致页面刷新,而是希望通过 AJAX(如 fetch)在后台异步提交数据。

HTML 结构:

html
<form id="myForm">
  <input type="text" id="username" placeholder="输入用户名" />
  <button type="submit">提交</button>
</form>

JavaScript 实现:

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()阻止默认动作控制浏览器对特定元素的预设行为自定义链接点击、表单提交等行为。

基于 VitePress 的本地知识库