c事件和委托的区别_DOM 事件与事件委托

点击事件

<

提问1:点击了谁

  • 点击文字,算不算点击儿子?
  • 点击文字,算不算点击爸爸?
  • 点击文字,算不算点击爷爷?
  • 答案:都算

提问2:调用顺序

  • 点击文字,最先调用 fnYe / fnBa / fnEr 中的哪一个函数?
  • 答案:都行
  • IE5 认为先调 fnEr,网景认为先调 fnYe,然后掐上了
  • 最后闹到了 W3C

2002年,W3C 发布标准

  • 规定浏览器应该同时支持两种调用顺序
  • 首先按 爷爷 => 爸爸 => 儿子 顺序看有没有函数监听
  • 然后按 儿子 => 爸爸 => 爷爷 顺序看有没有函数监听
  • 由监听函数就调用,并提供事件信息,没有就跳过

术语

  • 从外向内找监听函数,叫事件捕获
  • 从内向外找监听函数,叫事件冒泡

疑问:这样是不是把 fnYe / fnBa / fnEr 都调用两次呐?=> 开发者可以自己选择把 fnYe 放在捕获阶段还是放在冒泡阶段

示意图

80eaefd864d998502fe69dd3210582f6.png

addEventListener

事件绑定API

baba

如果 bool 不传或为 falsy

就让 fn 走冒泡,即当浏览器在冒泡阶段发现 baba 有 fn 监听函数,就会调用 fn ,并提供事件信息。

如果 bool 为 true

就让 fn 走捕获,即当浏览器在捕获阶段发现 baba 有 fn 监听函数,就会调用 fn,并提供事件信息。

一个特例

背景

  • 只有一个 div 被监听(不考虑父子同时被监听)
  • fn 分别在捕获阶段和冒泡阶段监听 click 事件
  • 用户点击的元素就是开发者监听的

代码

  • div.addEventLisenter('clicl', f1)
  • div.addEventLisenter('clicl', f2, true)
  • 请问 f1 先执行还是 f2 先执行?
  • 如果把两行代码调换位置后,请问哪个先执行?
  • 答案:谁先监听谁先执行。 => 这是一个特例

target V.S. currentTarget

区别

  • e.target - 用户操作的元素
  • e.currentTarget - 开发者监听的元素
  • this 是 e.currentTarget,不推荐使用

举例

  • div > span {文字},用户点击文字
  • e.target 就是 span
  • e.currentTarget 就是 div

取消冒泡

捕获不可取消,但冒泡可以

  • e.stopPropagation() 可中断冒泡,浏览器不再向上走
  • 一般用于封装某些独立的组件

不可取消冒泡

有些事件不可取消冒泡

  • MDN 搜索 scroll event ,看到 Bubbles 和 Cancelable
  • Bubbles 的意思是该事件是否冒泡
  • Cancelable 的意思是开发者是否可以取消冒泡

上面提到 scroll ,那么如果阻止滚动

首先scroll 事件不可取消冒泡

  • 阻止 scroll 默认动作没用,因先有滚动才有滚动事件
  • 要阻止滚动,可阻止 wheel 和 touchstart 的默认动作
  • 需要找准滚动条所在的元素
JS Bin​js.jirengu.com
3f7af68a233ca76e7ce7be77dc1990b8.png
  • 但是滚动条还能用,可用 CSS 让滚动条 display: none

CSS 也可以

  • 使用 overf: hidden 可以直接取消滚动条
  • 但此时 JS 依然可以修改 scrollTop

事件委托(event.target 属性可以实现事件委托

场景一

  • 现在需要给100个按钮添加点击事件,怎么办?
  • 答:监听这100个按钮的祖先,等冒泡的时候判断 target 是不是这100个按钮中的一个。

场景二

  • 现在要监听目前不存在的元素的点击事件,怎么办
  • 答:监听祖先,等点击的时候看看是不是我想要监听的元素即可

优点

  • 省监听数(内存)
  • 可以监听动态元素

封装事件委托

要求

  • 函数 on('click', '#div1', 'button',fn)
  • 当用户点击 #div1 里的 button 元素时,调用 fn 函数
  • 需要用到事件委托

答案一

  • 判断 target 是否匹配 'button'
const 

首先通过这个 on 函数理解事件委托,给传入 element 参数的元素添加一个监听,然后判断当前的 target 是否满足 selector,如果满足就调用函数,如果不满足就放过。

但是这个方法是有误区的,如果 传入 selector 参数的元素还被 span 包围了,也就是说 button 元素中还含有一个 span ,然后 span 元素里有文字内容,这时我点击 button,委托事件是不会触发的,因为实际上我点击的是 span 元素,例子如下所示:

const 

答案二

  • 递归判断 target / target 的爸爸 / target的爷爷
function 

JS 支持事件吗?

  • 支持,也不支持。上面所说的 DOM 事件不属于 JS 的功能,属于浏览器提供的 DOM 的功能
  • JS 只是调用了 DOM 提供的 addEventListener
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值