preventDefault vs stopPropagation vs stopImmediatePropagation

428 阅读2分钟

原文链接:medium.com/developers-…

前端页面由 HTML 构建,而绝大部分 HTML 构建的网页都离不开事件和 javascript image.png

当我们在使用 JS 创建应用程序的时候,会经常使用到 preventDefault. stopPropagation. stopImmediatePropagation,但是我们往往是不求甚解,一个不行就换下一个,总有一个行的~

但是你知道他们之间的区别是什么吗?

本文,我们将讨论它们的区别,并深入探究它们的具体使用场景

在理解它们仨之前,我们首先需要理解什么是 事件捕获事件冒泡

什么是事件捕获 和 事件冒泡

事件捕获和事件冒泡是事件(点击事件,键盘事件等)在DOM结构之间传递的两种不同方式

要明白这一点,让我们思考下面这段伪代码

<div class="parent" (onClick)="console.log('parent')">  
    <button class="child" (onClick)="console.log('child')"></button>  
</div>

事件捕获的意思是当我们点击这个按钮的时候,点击事件将从最外层逐级传递到最里面,因此,会输出如下结果:

parent  
child

image.png

事件冒泡和事件捕获正好相反,它从最里面逐级传递到最外层,输出结果如下:

child  
parent

image.png

现在,你理解了事件捕获和事件冒泡,我们就能理解 preventDefault(),stopPropagation(),stopImmediatePropagation()

event.preventDefault()

这个方法用于阻止浏览器在响应事件时的默认行为,比如:

  • 复选/单选框的选中和取消选中
  • 单击 input /textarea 字段将输入聚焦,并将光标放在 input/testarea 元素中

使用 preventDefault() 可以阻止 HTML 元素的默认行为

在点击 checkbox 复选框的时候,我添加了 preventDefault() ,可以看到复选框无法被选中 View JSFiddle here.

image.png

默认情况下,单击复选框上的事件/取消选中复选框,这是浏览器提供的默认行为。使用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 元素的时候:

  1. 阻止事件向上冒泡
  2. 阻止其它绑定在这个 html 元素上的事件函数的执行

因此,我们也可以理解为: stopImmediatePropagation = stopPropagation + (移除其他事件监听程序)