事件捕获和事件冒泡

今天把事件捕获和事件冒泡彻底搞懂了。来记录一下。
事件捕获和事件冒泡

当你监听一个事件的触发的时候,它会经历三个状态,第一个是捕获阶段,第二个是目标节点,第三个是冒泡阶段,画个图来表示一下。
事件捕获和事件冒泡
当我们触发某个DOM的监听事件的时候,捕获阶段会从外向内找到这个DOM节点,一般会在冒泡阶段执行监听事件。也就是说,当我们有如下这样的父子孙节点的时候,同时在父子孙身上都绑定有监听事件,它的打印顺序应该是1,2,3:那么怎样才能让我们在事件的捕获阶段就执行监听事件呢?那么就要提到addEventListener的参数了,它有三个参数,分别是event Type,callback,Boolean。分别代表着事件类型,回调函数,是否在事件捕获阶段就执行回调函数,默认为false,当我们把它设为true的时候它就表示会在事件捕获阶段执行回调函数:

  grandson.addEventListener('click',  grandsonEvent, true)  
  son.addEventListener('click',sonEvent, true)
  father.addEventListener('click',fatherEvent, true)

事件捕获和事件冒泡
那么这就完成了在事件捕获阶段去执行回调函数。接下来我们来考虑一下如何将事件冒泡给禁止,因为有时候事件冒泡会对我们的业务代码有不好的影响。
首先是w3c的方法是event.stopPropagation(),如果在目标元素上设置这个的话,就会阻止目标元素的事件冒泡到父级元素。如:


  grandson.addEventListener('click', grandsonEvent)  
  son.addEventListener('click',() => {
    sonEvent()
    event.stopPropagation()
  })
  father.addEventListener('click',fatherEvent)

事件捕获和事件冒泡
我们在son的回调函数里面使用了event.stopPropagrtion(),阻止它进一步的冒泡到father盒子上,所以最后打印结果是1,2.
那么事件冒泡能给我们带来什么好东西或者方便的东西吗?那肯定是有的,也就是我们常说的事件委托。

事件委托/事件代理

首先介绍一下我个人理解的事件委托的意思,就是将子组件要完成的回调函数绑定到父组件上面,然后由父组件代为调用。比如这个例子,每点击一个格子就要显示出它的颜色:

  <style>
    ul li {
      width: 100px;
      height: 200px;
    }
    .purple {
      background-color: rgb(170, 74, 170);
    }
    .pink {
      background-color: pink;
    }
    .skyblue {
      background-color: skyblue;
    }
    .aqua {
      background-color: aqua;
    }
    .gray {
      background-color: gray;
    }
    ul {
      display: flex;
      list-style: none;
      text-align: center;
      height: 300px;
      background-color: red;
    }
  </style>
</head>
<body>
  <ul>
    <li class="purple">紫色</li>
    <li class="pink">粉红色</li>
    <li class="skyblue">天蓝色</li>
    <li class="aqua">青色</li>
    <li class="gray">灰色</li>
  </ul>
</body>
<script>
  let ul = document.querySelector('ul')
  ul.addEventListener('click', (event) => {
    console.log(event.srcElement.innerHTML);
  })

</script>

事件捕获和事件冒泡
这样就可以很轻松的完成我们的代码。下次再面试到这个的话感觉我又能跟面试官battle几句了。冲冲冲。
事件捕获和事件冒泡

上一篇:JQuery


下一篇:JQ实现音乐插件并自动播放