前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS的事件冒泡和捕获

JS的事件冒泡和捕获

作者头像
用户3258338
发布2019-12-04 12:03:47
2.5K0
发布2019-12-04 12:03:47
举报

天时地利的迷信~


各位宝宝,最近怎么样?北京的冬天来了,好冷,幸好下了一场不大不小的雪,否则对冬天真是喜欢不起来。

事件机制


事件触发三个阶段:

  • window往事件触发处传播,遇到注册的捕获事件会触发
  • 传播到事件触发处时触发注册的事件
  • 从事件触发处往window传播,遇到注册的冒泡事件会触发

事件触发一般会按照?的顺序进行(W3C模型)

代码语言:javascript
复制
         1. 先从上往下捕获                    |                   | |  / \ ------------------| |--| |-----------------|   outer         | |  | |                ||    -------------| |--| |-----------     ||    |   inner     \ /  | |           |    ||   |                   |            |    ||    |  2. 到达目标元素后从下往上冒泡     |    ||    --------------------------------      ||        W3C event model                   |-------------------------------------------

但是有一个特例:如果给body中的子节点同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行。

代码语言:javascript
复制
// 以下会先打印冒泡然后是捕获node.addEventListener(  'click',  event => {    console.log('冒泡')  },  false)node.addEventListener(  'click',  event => {    console.log('捕获 ')  },  true)

我们来看一下如下代码到底是怎么的结果:

代码语言:javascript
复制
var selector = document.querySelector.bind(document);selector('div.outer').addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'outer clicked! '}, true)selector('div.inner').addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'inner clicked! '}, false)document.addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'document clicked! '}, true)

当点击innner元素时,如下元素发生了:

  1. 点击事件开始于捕获阶段,在此阶段浏览器会在所有祖先元素上查找点击事件处理函数(从document开始)
  2. 结果找到了2个,分别在document和outer上面,而且这两个事件处理函数的useCapture选项为true,说明他们被注册在捕获阶段的。于是,document和outer的点击处理函数被执行
  3. 继续向下寻找,直到到达inner元素本身,捕获阶段就此结束。此时进入冒泡阶段,inner上的时间处理器得到执行
  4. 事件命中元素后开始向上冒泡,一路查找是否注册了冒泡阶段的祖先元素上的时间处理器。由于没有找到因此什么也没发生。

最后的结果是

代码语言:javascript
复制
// logdocument clicked! outer clicked! inner clicked!

我们把时间注册在冒泡阶段(addEventListener的useCapture选项为false)

代码语言:javascript
复制
var selector = document.querySelector.bind(document);selector('div.outer').addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'outer clicked! '    console.log(e);}, false)selector('div.inner').addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'inner clicked! '    console.log(e);}, false)document.addEventListener('click', (e) => {    selector('p:first-of-type').textContent += 'document clicked! '}, false)

结果是:

代码语言:javascript
复制
// loginner clicked! outer clicked! document clicked!

愿我们有能力不向生活缴械投降---Lin

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档