美文网首页
捕获与冒泡

捕获与冒泡

作者: 独钓寒江月 | 来源:发表于2019-10-10 10:05 被阅读0次

当一个HTML元素触发一个事件时,该事件会在元素结点与根结点之间的路径传播。传播按顺序分为三个阶段:捕获阶段、目标阶段、冒泡阶段,这个传播过程就是 DOM 事件流。

事件捕获就是当一个HTML元素触发一个事件时,它的祖先节点都会收到捕获该事件。

  • 通过设置addEventListener的第三个参数可以决定事件是否在捕获阶段触发。
  • 通过event.stopPropagation()可以阻止事件冒泡。

一、定义

DOM结构是一个树型结构,当一个HTML元素触发一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为 DOM 事件流(DOM event flow )。

传播按顺序分三个阶段:

  1. 捕获阶段(capture phrase,从根节点document到目标节点,即最近的、最精确的元素节点,依次捕获触发的事件)
  2. 目标阶段(target phrase,目标节点上的事件触发按代码执行顺序触发)
  3. 冒泡阶段(bubbling phrase,从目标节点到根节点 )
    默认在捕获阶段不触发事件

二、演示

<div>
  <button>点击</button>
</div>

现在有一个div节点,div节点里面有一个button节点。

let div = document.getElementsByTagName('div');
div.addEventListener('click',(e)=>{
  console.log('div')
})
let button = document.getElementsByTagName('button');
button.addEventListener('click',(e)=>{
  console.log('button')
})

现在我们只看div节点和button节点,当我们点击button时会先后打印出buttondiv,因为addEventListener方法默认是让事件在冒泡阶段触发。如果我们设置addEventListener第三个参数useCapture的值为true,就会让事件在捕获阶段触发:

div.addEventListener('click',(e)=>{
  console.log('div')
},true)

这个时候点击button就会先触发divclick事件,再触发buttonclick事件。

三、阻止冒泡:event.stopPropagation()

stopPropagation方法会让事件传播到目标阶段后停止传播,所以也叫阻止冒泡。相当于让事件流只剩下捕获阶段和目标阶段。所以下面的代码会先后打印出div1button

button.addEventListener('click',(e)=>{
  e.stopPropagation()
  console.log('button')
})
div.addEventListener('click',(e)=>{
  console.log('div1')
},true)
div.addEventListener('click',(e)=>{
  console.log('div2')
})

也可以通过setTimeout来调整事件内代码执行顺序

四、马上停止传播:event.stopImmediatePropagation();

有个特例,如果目标阶段的节点绑定了多个事件,它们不会区分捕获和冒泡,事件触发的顺序为代码执行的顺序。

而且event.stopPropagation()在目标阶段不会生效。如果目标阶段有 a、b、c 三个触发事件会按序执行,在 b 事件里设置event.stopPropagation()并不会影响 c 事件的触发。 但是如果在 b 事件里设置event.stopImmediatePropagation()后 ,事件触发到b之后就会停止触发后面的所有事件。

五、发散

e.preventDefault() 阻止默认事件

在Vue中使用修饰符来实现

.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 开启捕获阶段 -->
<div @click.capture ="doThis"></div>

相关文章

  • JavaScript 事件捕获和冒泡

    JavaScript 事件捕获和冒泡 规范 在最新的 DOM 规范中,事件的捕获与冒泡是通过 addEventLi...

  • 冒泡与捕获

    在W3C模型中,事件的触发会前后发生两个过程,这两个过程分别为捕获阶段和冒泡冒泡。 捕获阶段:就是从元素的Wind...

  • 捕获与冒泡

    当一个HTML元素触发一个事件时,该事件会在元素结点与根结点之间的路径传播。传播按顺序分为三个阶段:捕获阶段、目标...

  • JS事件的冒泡捕获--发生了什么

    多次遇到事件冒泡与捕获相关的题目,冒泡和捕获机制在不同浏览器中的兼容性也不相同,IE中默认只支持冒泡机制,冒泡和捕...

  • JS事件冒泡与捕获(addEventListener)

    1、事件传播——冒泡与捕获 默认情况下,事件使用冒泡事件流,不使用捕获事件流。然而,在Firefox和Safari...

  • 我的前端入门笔记(11)--事件冒泡、捕获、代理

    1.事件冒泡与捕获 冒泡:先触发内部事件,再触发外部事件;捕获:先触发外部事件,再触发内部事件; addEvent...

  • Javascript DOM事件流向

    事件流向 先捕获然后处理,然后再冒泡出去 addEventListener false冒泡 true捕获 事件捕获...

  • 事件流 事件监听 (03)

    事件流 从页面接受事件的顺序, 分为 捕获与冒泡 1冒泡 从内往外 (事件的传递) 2捕获 从外往内 (bod...

  • 2022-01-09 浏览器相关面试知识点

    一.详解浏览器事件捕获与冒泡 1. 事件委托/事件代理 捕获阶段-->目标阶段-->冒泡阶段 第三个参数为true...

  • JavaScript事件捕获冒泡与捕获

    事件流 JavaScript中,事件流指的是DOM事件流。 概念 事件的传播过程即DOM事件流。 事件对象在 DO...

网友评论

      本文标题:捕获与冒泡

      本文链接:https://www.haomeiwen.com/subject/scaxyctx.html