stopPropagation() 和 preventDefault() 是事件对象(event)上两个非常重要的方法,它们的作用完全不同。理解它们的区别对于处理 DOM 事件至关重要。
影响范围: 只影响当前事件本身的默认动作,不影响事件在 DOM 树中的传播(冒泡或捕获)。
示例:
const link = document.getElementById('myLink');
link.addEventListener('click', function(event) {
event.preventDefault(); // 阻止链接跳转到 href 指定的页面
console.log('链接被点击了,但页面没有跳转');
// 事件仍然会冒泡到父元素
});
示例:
const child = document.getElementById('child');
const parent = document.getElementById('parent');
parent.addEventListener('click', function() {
console.log('父元素被点击');
});
child.addEventListener('click', function(event) {
event.stopPropagation(); // 阻止点击事件冒泡到父元素
console.log('子元素被点击');
// 注意:如果 child 是一个链接,它仍然会跳转(默认行为未被阻止)
});
特性 |
|
|
---|---|---|
主要目的 | 阻止默认行为 | 阻止事件传播 |
影响默认行为 | ✅ 是 | ❌ 否 |
影响事件冒泡/捕获 | ❌ 否 | ✅ 是 |
调用后事件处理 | 当前元素的其他处理函数和父元素的处理函数仍会执行 | 当前元素的其他处理函数仍会执行,但父元素的处理函数不会执行 |
典型用例 | 阻止链接跳转、表单提交 | 防止点击子元素时触发父元素的逻辑 |
在实际开发中,经常需要同时调用这两个方法。
经典例子:点击模态框内部,既不关闭模态框(阻止冒泡),也不执行链接跳转(阻止默认行为)。
const modal = document.getElementById('modal');
const modalLink = document.getElementById('modalLink');
// 点击模态框背景关闭
modal.addEventListener('click', function(event) {
// 假设点击背景(非内容区域)才关闭
if (event.target === modal) {
modal.style.display = 'none';
}
});
// 点击模态框内的链接
modalLink.addEventListener('click', function(event) {
event.preventDefault(); // 1. 阻止链接跳转 (默认行为)
event.stopPropagation(); // 2. 阻止事件冒泡到 modal,防止模态框关闭
console.log('模态框内的链接被点击,但页面没跳转,模态框也没关闭');
});
还有一个相关方法 stopImmediatePropagation(),它比 stopPropagation() 更彻底:
element.addEventListener('click', function(e) {
console.log('Handler 1');
e.stopImmediatePropagation(); // 阻止后续处理函数和冒泡
});
element.addEventListener('click', function(e) {
console.log('Handler 2'); // 这个不会执行!
});
parentElement.addEventListener('click', function() {
console.log('Parent clicked'); // 这个也不会执行!
});
简单记忆:
https://blog.xqlee.com/article/2508271716463630.html