浏览器-事件流理解总结

关于事件流机制的理解以及对e.target 和 e.currentTarget问题处理

一 DOM事件流

DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素节点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。

上面这句话来自百度百科:DOM事件流,该如何理解这句话呢,如图所示,

在这里插入图片描述

当有事件触发时,从DOM的根节点开始,向内传递,这一过程可以理解成①②③④捕获阶段;如果图中的d节点被触发,事件整个传递到达目标阶段,该阶段结束后,事件会向上传递,这一过程按照水底的气泡一样向上漂,称之为的⑤⑥⑦⑧ 冒泡阶段

结合图和上面的描述可以总结为

在DOM兼容浏览器中,事件流分为3个阶段:

  1. 捕获阶段:事件从Document节点自上而下向目标节点传播的阶段;
  2. 目标阶段:真正的目标节点正在处理事件的阶段;
  3. 冒泡阶段:事件从目标节点自下而上向Document节点传播的阶段

二 捕获事件流

捕获事件流可以在支持W3C 标准的浏览器中使用addEventListener处理,在菜鸟教程:addEventListener 中在线体验.

该函数有三个参数:

  1. 事件名
  2. 触发执行函数
  3. 冒泡阶段还是捕获阶段执行,默认是在冒泡阶段执行

为了理解这个问题,我在网上看到一道十分有意思的题 事件流经典问题:e.target 和 e.currentTarget 有什么区别? ,一起来看下,加深理解.

    <div id="a">
      <div id="b">
        <div id="c">
          <div id="d">点击这里</div>
        </div>
      </div>
    </div>
const a = document.getElementById('a')
const b = document.getElementById('b')
const c = document.getElementById('c')
const d = document.getElementById('d')
a.addEventListener('click', (e) => {
  const {
    target,
    currentTarget
  } = e
  console.log(`target是${target.id}`)
  console.log(`currentTarget是${currentTarget.id}`)
})
b.addEventListener('click', (e) => {
  const {
    target,
    currentTarget
  } = e
  console.log(`target是${target.id}`)
  console.log(`currentTarget是${currentTarget.id}`)
})
c.addEventListener('click', (e) => {
  const {
    target,
    currentTarget
  } = e
  console.log(`target是${target.id}`)
  console.log(`currentTarget是${currentTarget.id}`)
})
d.addEventListener('click', (e) => {
  const {
    target,
    currentTarget
  } = e
  console.log(`target是${target.id}`)
  console.log(`currentTarget是${currentTarget.id}`)
})

想想输出的结果是什么?

addEventListener第三个参数不设置默认是冒泡顺序,当触发d时,呈现的结果如下

target是d currentTarget是d
target是d currentTarget是c
target是d currentTarget是b
target是d currentTarget是a

addEventListener第三个参数设置为true,看看捕获阶段呢?

target是d currentTarget是a
target是d currentTarget是b
target是d currentTarget是c
target是d currentTarget是d

总结如下:

  1. e.target触发事件的元素
  2. e.currentTarget绑定事件的元素

三 事件委托

通过上面的例子,我们可以很清晰的发现,如果当前父级元素下有若干个子级元素,对父级做监听后,当我们通过addEventListener回调函数返回的e.tartget便能得到触发事件的元素.

    <div id='list'>
        <div id='item-1'>item-1</div>
        <div id='item-2'>item-2</div>
        <div id='item-3'>item-3</div>
        <div id='item-4'>item-4</div>
    </div>

通过给id为list的元素添加监听,在点击列表中的元素,便可实现事件委托,事件委托便是处理事件处理程序过多问题的一种解决方案

四 阻止事件流

阻止事件流常用的两种种方式

e.stopPropagation():阻止目标元素的事件冒泡到父级元素;

e.preventDefault():取消一个目标元素的默认行为(例如:a链接,input标签的submit等)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值