【JS中stopPropagation和stopImmediatePropagation作用及其区别】

1. 前言

在了解这两个函数的区别前,我们先来知道这两个函数是用来做什么的。

首先,在JS中我们可以给标签对象添加监听器。这里为了方便说明,使用onclick(鼠标点击事件)来说明。这里给document(浏览器显示部分)和三个标签ID分别为outter、inner、neighbour添加点击事件。

HTML代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <style>
        * {
            margin: 0px;
            padding: 0px;
        }
        #outter {
            width: 300px;
            height: 300px;
            background-color: red;
        }
        #inner {
            width: 150px;
            height: 150px;
            background-color: skyblue;
        }
        #neighbour {
            width: 150px;
            height: 150px;
            background-color: lightgreen;
            position: absolute;
            top: 150px;
            left: 150px;
            /* 给neighbour添加定位,使其也在outter的内部 */
        }
    </style>
</head>
<body>
    <div id="outter">
        <div id="inner"></div>
    </div>
    <!-- 这里虽然neighbour不是outter的子级,但是通过css可以将其定位到outter的内部 -->
    <div id="neighbour"></div>

    <script>
        // 选中标签对象
        var outter = document.getElementById("outter");
        var inner = document.getElementById("inner");
        var neighbour = document.getElementById("neighbour");

        // 给document添加点击事件
        document.addEventListener("click", (event)=>{
            console.log("document点击事件被触发!!");
        });

        // 给outter添加点击事件
        outter.addEventListener("click",(event)=>{
            console.log("outter点击事件被触发!!");
        });
        
        // 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!");
        });
        
        // 给neighbour添加点击事件
        neighbour.addEventListener("click",(event)=>{
            console.log("neighbour点击事件被触发!!");
        });
        
    </script>
</body>
</html>

2. 函数产生的根本因素(冒泡事件)

如图一所示:这时候,我们去点击inner也就点这个天空蓝(skyblue)的部分的时候就会触发到三个事件。这就是冒泡事件,观察我们可以发现:冒泡事件的触发顺序是从子级到父级。
而我们在正常的编写JS事件的时候,是不希望点击子集的时候同时触发父级的同类别事件监听(比如这里是对子级onclick,我们并不希望父级的onclick也触发)。

如图二所示:有趣的是,这时候若用定位将同级标签(不是父子级关系)移动到有共同区域的地方。点击那个共同区域的时候,这时候就只会触发更前面(可以用z-index改变)且后来者会更优先(两个覆盖的标签z-index相等),即视觉上哪个标签先就触发哪个标签。

  • 图一
    在这里插入图片描述
  • 图二
    在这里插入图片描述

3. 两者的作用和区别,及其使用详解

介绍了这么多,我们终于可以步入主题了,stopPropagation()和stopImmediatePropagtion()函数到底有什么用,它们之间有什么区别呢?

3.1 stopPropagation()和stopImmediatePropagtion()函数的作用

作用:刚刚说到,我们在触发一个对象的事件监听时不想触发其父级的同类型事件监听,也就是对子级点击(onclick)的时候不想触发父级的点击事件,只触发子级的点击事件,这时候我们的这个函数就排上用场了,它可以防止冒泡事件的产生,即点击当前的子级时,它的触发域只有自己本身,不会涉及到其父级。比如这时候我们给inner添加一个stopPropagtion()或者stopImmediatePropagation(),就会消除它产生的冒泡事件,但是并不会消除outter到document的冒泡事件,点击效果如图三、图四所示。

具体代码如下:

// 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!");
            
            //防止inner的冒泡事件,阻止其父级触发相同类型的事件
            event.stopPropagation(); 
        });
  • 图三(点击inner触发的)
    在这里插入图片描述
  • 图四(点击outter且非inner、非neighbour的区域)
    在这里插入图片描述

因为只限制了inner的冒泡事件,这还不足够,所以我们在编码时候,应为所有到非documen的标签对象的事件触发添加一个stopPropagation函数,这样就可以成功的防止冒泡事件对代码结果的影响了~

具体代码如下:

// 给document添加点击事件
        document.addEventListener("click", (event)=>{
            console.log("document点击事件被触发!!");
           	//document不需要添加防止冒泡事件触发的函数
        });

        // 给outter添加点击事件
        outter.addEventListener("click",(event)=>{
            console.log("outter点击事件被触发!!");
            
            //防止outter的冒泡事件,阻止其父级触发相同类型的事件
            event.stopPropagation();
        });
        
        // 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!");
            
            //防止inner的冒泡事件,阻止其父级触发相同类型的事件
            event.stopPropagation();
        });
        
        // 给neighbour添加点击事件
        neighbour.addEventListener("click",(event)=>{
            console.log("neighbour点击事件被触发!!");
            
            //防止neighbour的冒泡事件,阻止其父级触发相同类型的事件
            event.stopPropagation();
        });

3.2 区别

区别:stopImmediatePropagtion()函数在使用上比stopPropagtion()函数更为严格,后者stopPropagtion只限制了父级的冒泡触发,而前者stopImmediatePropagtion()不仅限制了父级的同类型事件冒泡触发还限制了自己的同类型事件冒泡触发,因为在DOM(document object module)中一个对象可以添加多个同类型的事件监听,称为DOM二级事件监听,也就是说一个对象可以添加多个onclick事件。

具体代码如下:

// 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第一个!!!");
            event.stopPropagation();
        });
        // DOM二级事件监听,给inner添加多个onclick事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第二个!!!");
            event.stopPropagation();
        }); 
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第三个!!!");
            event.stopPropagation();
        });

虽然这时候我们对inner添加了stopPropagation()函数来防止冒泡事件对其父级的同类型(onclick)事件触发。但是这时候我们点击inner会触发它的三个onclick事件。如图五所示:

  • 图五
    在这里插入图片描述

这里就可以体现出stopImmediatePropagation()函数的区别了,这时候若我们给第一个事件(符合代码的顺序执行逻辑,先写的为第一个)添加stopImmediatePropagation()而其他不加,这时候再点击inner,后面的两个点击事件(onclick)就不会触发。如图六所示:

具体代码如下:

// 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第一个!!!");
            
            //只对第一个事件添加stopImmediatePropagation()
            event.stopImmediatePropagation();
        });
        // DOM二级事件监听,给inner添加多个onclick事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第二个!!!");
            // event.stopPropagation();
        }); 
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第三个!!!");
            // event.stopPropagation();
        });
  • 图六
    在这里插入图片描述

细节点评:多个onclick事件只需要其中有一个添加了stopPropagtion()或者stopImmediatePropagtion()就可以阻止父级的同类型事件冒泡触发。

可以看见这时候后面两个事件将不会触发,这就是stopImmediatePropagation()函数的使用。与stopPropagtion对父级同类型冒泡事件触发防止操作的类比,这时候若对第二个事件添加stopImmediatePropation()则第三个事件不会触发,而第一个事件依旧会触发。如图七所示:

具体代码如下:

// 给inner添加点击事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第一个!!!");
            // event.stopImmediatePropagation();
        });
        // DOM二级事件监听,给inner添加多个onclick事件
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第二个!!!");
            //只对第二个事件添加stopImmediatePropagation()
            event.stopImmediatePropagation();
        }); 
        inner.addEventListener("click",(event)=>{
            console.log("inner点击事件被触发!!,这是第三个!!!");
            // event.stopPropagation();
        });
  • 图七
    在这里插入图片描述

综上所述,若我们防止一个标签本身同类事件的某一个事件后续的同类型事件的冒泡触发,就可以在当前事件加上stopImmediatePropagation()函数,就像这里演示的一样。
①若只想触发inner的第一个onclick事件,只需在第一个事件添加stopImmediatePropagation()函数。
②若不想触发inner第n个onclick事件后的onclick事件,只需在这个第n个onclick事件添加stopImmediatePropagation()函数即可。

4. 结尾

讲到这里,相信大家也对这两个函数的作用和区别都有了大致的了解~
祝大家进步多多,天天向上,开开心心每一天!!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值