前端页面由 HTML 构建,而绝大部分 HTML 构建的网页都离不开事件和 javascript
当我们在使用 JS 创建应用程序的时候,会经常使用到 preventDefault. stopPropagation. stopImmediatePropagation,但是我们往往是不求甚解,一个不行就换下一个,总有一个行的~
但是你知道他们之间的区别是什么吗?
本文,我们将讨论它们的区别,并深入探究它们的具体使用场景
在理解它们仨之前,我们首先需要理解什么是 事件捕获 和 事件冒泡?
什么是事件捕获 和 事件冒泡
事件捕获和事件冒泡是事件(点击事件,键盘事件等)在DOM结构之间传递的两种不同方式
要明白这一点,让我们思考下面这段伪代码
<div class="parent" (onClick)="console.log('parent')">
<button class="child" (onClick)="console.log('child')"></button>
</div>
事件捕获的意思是当我们点击这个按钮的时候,点击事件将从最外层逐级传递到最里面,因此,会输出如下结果:
parent
child
事件冒泡和事件捕获正好相反,它从最里面逐级传递到最外层,输出结果如下:
child
parent
现在,你理解了事件捕获和事件冒泡,我们就能理解 preventDefault(),stopPropagation(),stopImmediatePropagation()
event.preventDefault()
这个方法用于阻止浏览器在响应事件时的默认行为,比如:
- 复选/单选框的选中和取消选中
- 单击 input /textarea 字段将输入聚焦,并将光标放在 input/testarea 元素中
使用 preventDefault() 可以阻止 HTML 元素的默认行为
在点击 checkbox 复选框的时候,我添加了 preventDefault() ,可以看到复选框无法被选中 View JSFiddle here.
默认情况下,单击复选框上的事件/取消选中复选框,这是浏览器提供的默认行为。使用event.preventdefault(),我们可以抑制浏览器的默认行为,并因此可以自行处理事件。
event.stopPropagation()
这个方法用于阻止浏览器中的事件在的 捕获/冒泡阶段 的传播。
思考下面的 HTML 伪代码:
<div class="parent" (onClick)="console.log('parent')">
<button class="child" (onClick)="console.log('child')"></button>
</div>
如果浏览器支持事件冒泡,将输出如下结果:
child
parent
如果我们改变这个函数的点击事件
<div class="parent" (onClick)="console.log('parent')">
<button class="child" (onClick)="buttonClick(event)"></button>
</div>
<script>
function buttonClick(event) {
event.stopPropagation();
console.log('child');
}
</script>
...将会输出
child
因为我们在点击事件发生的时候阻止了事件的传播(在这个例子里是:事件冒泡),将只会在控制台打印出 child
event.stopImmediatePropagation()
如果我们给一个 HTML 元素同时绑定了多个事件 思考下面这段代码: (View JSFiddle here.)
<script>
$("div").click(function(event) {
event.stopImmediatePropagation();
alert('First click triggered');
});
$("div").click(function(event) {
// This function won't be executed
alert('Second click triggered');
});
</script>
<div>Click me</div>
加上了 event.stopImmediatePropagation(),事件触发之后,绑定的其它事件处理程序将会被阻止执行
总结就是,在点击 div 元素的时候:
- 阻止事件向上冒泡
- 阻止其它绑定在这个 html 元素上的事件函数的执行
因此,我们也可以理解为:
stopImmediatePropagation = stopPropagation + (移除其他事件监听程序)