什么是事件冒泡?

        一想到“冒泡”这两个词会想到什么?想必然,那就是气泡自下而上的从水底往上生的场景,但是我们也知道,水在往上升的过程中,也会经历不同的高度。由此场景,那么想必然,冒泡的原理就可以很轻易的被理解啦。

        我们知道,我们平时缩写的所看到的页面,都是由文档流即DOM树组成的,那么当我们在一个时间出发某个时间的时候,这个事件就会像这个气泡一样,从DOM树的底层,逐步向上传递,一直到DOM的根节点。当然,这事件冒泡的过程中,需要注意的一个点事,只有子元素和父级元素都有绑定了相同的事件,那么触发子组件的事件的时候,才会冒泡到父级组件中,这就是冒泡的基本原理。

不过我们也要清楚一点是,在不同浏览器中,冒泡是不一样的

  • IE<11:div->body->html->document
  • 其他内核:div>body->html->window

注意:在JavaScript中 ,并非所有的事件都可以冒泡,像blur、unload、load等事件就不能冒泡

示例demo

<template>
  <div class="father" @click="handleClickFather">
    我是父元素
    <div class="son" @click="handleClickSon">我是子元素 </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
    }
  },
  methods: {
    handleClickFather(){
      console.log('点击了father')
    },
    handleClickSon(){
      console.log('点击了son')
    }
  },
}
</script>
<style lang="css">
 .father {
   background:pink;
   height: 200px;
   width: 200px;
   padding: 20px;
   margin: 100px auto;
 }
 .son{
  width: 100px;
  height: 100px;
  background: #fff;
  line-height: 100px;
  text-align: center;
  cursor: pointer;
  margin-top: 20px;
 }
</style>

点击子元素时候的输出结果:

点击父元素时的输出结果:

 以上例子我们可以看到,当我点击子元素时候,父元素绑定的点击事件也被触发了,那我们应该如何阻止这种事件的传递呢?

阻止冒泡事件

  • 原生js中

在W3C中,规定DOM标准通过调用event对象的stopPropagation()方法即可阻止冒泡型事件的进一步传递。

<body>
  <div id="fater">
    我是父元素
    <div id="son">我是子元素</div>
  </div>
  <script>
    var father = document.getElementById('father');
    var child = document.getElementById('child');
    father.addEventListener("click", function () {
      if(event && event.stopPropagation){
        event.stopPropagation() // 非IE浏览器
      }else{
        event.cancelBubble = true; //IE浏览器
      }
      console.log('我是父级元素')
    }, false)
    child.addEventListener("click", function () {
      if (event && event.stopPropagation) {
        event.stopPropagation() // 非IE浏览器
      } else {
        event.cancelBubble = true; //IE浏览器
      }
      console.log('我是子集元素')
    }, false)
  </script>
</body>
  • Vue中(使用.stop指令)

冒泡事件在Vue中的应用

场景:(类似于百度搜索功能)

 实现:

 

 说明:这里一共绑定了三个事件,①是给最外层父级元素绑定close事件,②是给下拉框绑定closeTop事件,③是给下拉框的子项绑定handleClickCompanyItem事件。作用解释如下:

  • ③:点击下拉款子元素之后,关闭记录此次选择的值并关闭下拉框
  • ②:点击下拉框的时候保持下拉框可见
  • ①:点击父元素内所有元素的时候关闭下拉框

 由于这里的场景是点击下拉框子项的时候关闭下拉框,点击下拉框的时候保持打开,点击下拉框以外的元素关闭下拉框,所以我这里没有使用.stop来阻止冒泡事件。因此下面的事件就会各司其职。当点击子项的时候,由于父级和祖级的组件都绑定了相同类型的点击事件,因此会不断的向上冒泡,因此是这么一个过程:隐藏->显示->隐藏

冒泡事件在Vue中的应用扩展

假设这里没有点击子项关闭下拉框的需求,那么此时可以去掉子项的handleClickCompanyItem()事件,然后在下拉框事件上加上.stop的指令,这时候就会阻止事件向上冒泡。此时就是点击下拉框元素保持显示,点击除了下拉框意外的元素則會隐藏下拉框,因为已经阻止了事件向上冒泡,自然不会触发祖组件中的close事件。

Logo

前往低代码交流专区

更多推荐