JavaScript之阻止冒泡和取消默认事件

冒泡和捕获是 JS 中事件的两种传递方式。在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素。

在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件。

冒泡和捕获

参考以下代码:

1
2
3
4
5
<div id="level1">
<div id="level2">
<div id="level3"></div>
</div>
</div>
1
2
3
4
5
window.onload = () => {
$('#level1').addEventListener('click', () => {console.log('1');});
$('#level2').addEventListener('click', () => {console.log('2');});
$('#level3').addEventListener('click', () => {console.log('3');});
};

在这个例子中,id 为 level3 的元素在 level2 元素内部,而 level2 元素又在 level1 的元素内部,因此点击了 level3 的元素,这个点击事件也会传递给 level2 和 level1 的元素,这时会输出 3 2 1。这就是冒泡。

而为了触发 捕获,则需要将 addEventListener 的第三个参数设置为 true(默认是 false),这时就会输出 1 2 3

阻止事件传递

为了在点击 level3 元素时,不发生 level1 和 level2 元素的点击事件,就需要对事件传递进行阻止。

w3c 的方法是 e.stopPropagation(),也是目前最常使用的方法(兼容性为除了 IE9 以下,Edge12 以下的所有浏览器),IE 则是使用 e.cancelBubble = true(IE6 7 8)

stopPropagation 是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但不会阻止默认行为。

取消默认事件

w3c 的方法是 e.preventDefault() ,IE 则是使用 e.returnValue = false;

preventDefault 它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。既然是说默认行为,当然是元素必须有默认行为才能被取消。如链接 <a>,提交按钮 <input type=”submit”>等。当 Event 对象的 cancelable 为 false 时,表示没有默认行为,这时即使有默认行为,调用 preventDefault 也是不会起作用的。

比如,用来禁止选择网页上的文字:

1
2
3
document.addEventListener('selectstart', function(e){
e.preventDefault();
})

return false

return false 等效于同时调用 e.preventDefault()e.stopPropagation()

return false 除了阻止默认行为之外,还会阻止事件冒泡。

在 jQuery 的源码中,有如下代码:

1
2
3
4
if (ret === false) {
event.preventDefault();
event.stopPropagation();
}