Appearance
目录
在事件处理中,有时我们需要更精细地控制事件的行为。浏览器为我们提供了两个强大的工具: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() | 阻止默认动作 | 控制浏览器对特定元素的预设行为。 | 自定义链接点击、表单提交等行为。 |