DOM事件-冒泡和捕获

141 阅读2分钟

在讲捕获和冒泡之前我们先看一个例子

<div class="grandpa">
  <div class="papa">
    <div class="child">
      <button class="button">
      文字
      </button>
    </div>
  </div>
</div>

给每个层级加上事件监听,如果点击了文字,就打出数字

grandpa.addEventListener('click', () => {
  console.log(1)
})
papa.addEventListener('click', () => {
  console.log(2)
})
child.addEventListener('click', () => {
  console.log(3)
})
button.addEventListener('click', () => {
  console.log(4)
})

打印出了1,2,3,4.就是说我们点击了文字,不仅仅是打印出了数字4,它的上级也都做出了响应。

也就是说我们点击了文字,相当于点击了"child""papa""grandpa",但这里就有问题,点击了文字,先调用的那个函数,有两个方案:

  1. fn(grandpa)=>fn(papa)=>fn(child)=>fn(button)
  2. fn(button)=>fn(child)=>fn(papa)=>fn(grandpa)

事实上两中路径都可以,而路径1就是捕获,路径2就是冒泡

捕获(Capture page)

浏览器检查元素的最外层祖先,是否在捕获阶段中注册了一个onclick事件处理程序,如果是,则运行它。 然后,它移动到中单击元素的下一个祖先元素,并执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。

冒泡(Bubbling page)

浏览器检查实际点击的元素是否在冒泡阶段中注册了一个onclick事件处理程序,如果是,则运行它 然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达元素。

区分事件冒泡和捕获

xxx.addEventListener('click',fn,bool)
  • 如果bool不传或者传的为falsy值,就是走冒泡,当游览器在冒泡阶段发现有事件监听,就调用函数,并提供事件信息。

  • 如果bool为true,就是走捕获,当游览器在捕获阶段发现有事件监听,就调用函数,并提供事件信息。

取消事件冒泡

x.stopPropagation()

可以取消冒泡,一般用于封装某些独立的组件。