JavaScript基础之冒泡/捕获事件

JavaScript的冒泡事件和捕获事件是每一个前端开发者都会经常遇到的问题。最近遇到这个问题时,发现自己对它们还是一知半解,现在是时候该彻底的弄懂它们了。

1、定义

一个事件发生后,会在子元素和父元素之间传播。这种传播分成三个阶段:

  • 第一阶段:从window对象传导到目标节点(外层传到内层),称为“捕获阶段”。
  • 第二阶段:在目标节点上触发,称为“目标阶段”。
  • 第三阶段:从目标节点传导回window对象(从内层传回外层),称为“冒泡阶段”

2、应用

本文中我们用addEventListener() 方法来演示JavaScript的冒泡/捕获事件。
addEventListener(type, listener[, useCapture])方法接收三个参数,type:事件名称,listener:监听函数(如click、keydown等),useCapture:布尔值,表示监听函数是否在捕获阶段触发,默认为false(监听函数在冒泡阶段触发)。
纸上得来总觉浅,实践出真知。

   <style>
        #parent{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
        #child{
            width: 50px;
            height: 50px;
            border: 1px solid blue;
        }
    </style>
    <div id="parent">
        <div id="child"></div>
    </div>
    <script>
    var parent = document.getElementById('parent');
    var child = document.getElementById('child');
     parent.addEventListener('click',function(e){
        console.log('我是parent');
    },false)

    child.addEventListener('click',function(e){
        console.log('我是child');
    },true)
   </script>

在上面的代码中,我们将parent.addEventListener的第三个参数设为false,表示监听函数在冒泡阶段触发。也就是说会先打印child的日志,后打印parent的日志。
在这里插入图片描述
打印结果和我们想的一样。
下面我们把parent.addEventListener的第三个参数设为true,表示监听函数在捕获阶段触发。相信你一定知道打印结果了吧。
在这里插入图片描述
知道了冒泡事件和捕获事件的应用场景,但是这并没有结束。在类似于上面的场景中,很多时候我们在点击child这个div的时候,不想触发parent的点击事件,这就是我们平常说的阻止冒泡事件。如何阻止呢?直接在child的监听函数中调用事件对象的stopPropagation方法就可以。

  parent.addEventListener('click',function(e){
        console.log('我是parent');
    },false)

    child.addEventListener('click',function(e){
        e.stopPropagation()
        console.log('我是child');
    },false)

那么如何阻止捕获事件呢?同样也是调用stopPropagation方法,不过这次是在parent的监听函数中调用,同时把parent的监听函数第三个参数设为true。

  parent.addEventListener('click',function(e){
        e.stopPropagation()
        console.log('我是parent');
    },true)

    child.addEventListener('click',function(e){
        console.log('我是child');
    },false)

结果就只会打印parent监听函数的日志了,实际工作中很少会有这样的需求,这里只做演示使用。
总结:阻止冒泡事件就是阻止内层的事件不再往外层传播,所以stopPropagation方法要加在内层的监听函数中,同时内层监听函数的第三个参数设为false;
阻止捕获事件就是阻止外层事件不再往里面传播,所以stopPropagation方法要加在外层的监听函数中,同时外层监听函数的第三个参数设为true;

3、在vue中阻止冒泡/捕获

vue中click事件默认是冒泡模式,就是先相应内层的点击事件,再相应外层的点击事件。

  <div class="parent" @click="parentClick">
      <div class="child" @click="childClick"></div>
    </div>
      methods: {
    parentClick () {
      console.log('我是parent')
    },
    childClick () {
      console.log('我是child')
    }
  }

比如上面的代码,点击类名为child的div,打印结果是先打印"我是child",再打印“我是parent”。在vue中如何阻止冒泡事件呢?也很简单,直接在里面的div的@click后面添加vue提供的修饰符.stop即可。

  <div class="parent" @click="parentClick">
      <div class="child" @click.stop="childClick"></div>
    </div>

这样就只会打印“我是child”一行日志了。
同时,vue也提供了事件捕获模式的修饰符.capture,我们在外面div的@click后面加上这个修饰符

  <div class="parent" @click.capture="parentClick">
      <div class="child" @click="childClick"></div>
    </div>

打印结果是什么呢?跟默认的冒泡模式刚好相反,先打印"我是parent",再打印“我是child”。那么问题来了,在vue中如何阻止捕获事件呢?和上面的阻止冒泡一样,只需要在.capture修饰符后面再加上.stop修饰符就可以了(修饰符是可以串联的)。

 <div class="parent" @click.capture.stop="parentClick">
      <div class="child" @click="childClick"></div>
    </div>

打印结果就只有“我是parent”一行日志了。

扫描二维码关注公众号,回复: 11602721 查看本文章

猜你喜欢

转载自blog.csdn.net/zhang070514/article/details/108344341