stopPropagation 不能阻止默认动作的方法,也不能阻止附加到相同元素的相同事件类型的其他事件处理器。如果要阻止这些相同事件类型处理器的运行,请使用 stopImmediatePropagation() 方法。
案例一:点击按钮时,输出 click1, click2, parent
<div >
<button>按钮</button>
</div>
<style> div { padding: 20; outline: 1px solid black; } </style>
<script>
document.querySelector('div').onclick = e => {
console.log('parent');
}
document.querySelector('button').addEventListener('click', (e) => {
// e.stopPropagation()
// e.stopImmediatePropagation()
console.log('click1');
}/* , true */)
document.querySelector('button').addEventListener('click', () => {
console.log('click2');
}/* , true */)
</script>
案例二:使用 e.stopPropagation() 阻止事件冒泡,但不阻止相同元素的相同事件类型的事件处理程序。点击按钮时,只输出 click1, click2。
相同事件类型,指的是 type 和 capture 都相同!
<div >
<button>你好</button>
</div>
<style> div { padding: 20; outline: 1px solid black; } </style>
<script>
document.querySelector('div').onclick = e => {
console.log('hello');
}
document.querySelector('button').addEventListener('click', (e) => {
e.stopPropagation()
// e.stopImmediatePropagation()
console.log('click1');
}/* , true */)
document.querySelector('button').addEventListener('click', () => {
console.log('click2');
}/* , true */)
</script>
案例三:使用 e.stopImmediatePropagation() 阻止事件冒泡,同时阻止相同元素的相同事件类型的事件处理程序。点击按钮时,只输出 click1。
<div >
<button>你好</button>
</div>
<style> div { padding: 20; outline: 1px solid black; } </style>
<script>
document.querySelector('div').onclick = e => {
console.log('hello');
}
document.querySelector('button').addEventListener('click', (e) => {
// e.stopPropagation()
e.stopImmediatePropagation()
console.log('click1');
}/* , true */)
document.querySelector('button').addEventListener('click', () => {
console.log('click2');
}/* , true */)
// 如果把这里的 capture 设置为 true,则两个事件处理程序的事件类型不同
// 此时 stopImmediatePropagation 无法阻止这里的 click2 的输出
</script>
总结
- 点击 div 中的 button 时,父元素 div 无法阻止事件传播给 button!只有子元素 button 可以阻止事件冒泡给 div,或者阻止事件被 div 捕获。
- stopPropagation 不能阻止附加到相同元素的相同事件类型的其他事件处理器。
- 相同事件类型,指的是 type 和 capture 都相同!
- 如果要阻止相同元素的相同事件类型的其他事件处理器,请使用 stopImmediatePropagation() 方法。