D24 - 走!去浏览器偷听 Capturing & Bubbling

前言

这篇介绍 DOM Event Listener - 事件监听 (总觉得监听这个翻译很有抓奸的画面感?!)

实作:利用捕获机制设计灯泡渐进式的关灯效果 💡💡💡

所谓的监听事件

昨天的 cookie generator 点击按钮时产生饼乾,使用的是 事件绑定,也就是在 html 的按钮标签加上属性 onclick = 'addCookie()' ,这种直接写在 html 上是比较旧式的写法,JavaScrip 和 html 写在一起看起来比较不简洁以外,也容易有XSS 攻击事件的风险,因此後来新的写法是透过 监听事件 addeventListener 做绑定。
(两种方法都练习看看过才有更深刻的感觉~)

但不管是哪种写法,在 DOM 上的监听事件都必须设定三个主轴:

  1. Event Target 监听的对象:ex. 按钮
  2. Event 监听的事件:ex. 点击
  3. Event Handler 监听事件发生时的应对动作,ex. 产生饼乾

那我们监听的对象是谁呢?

主要的目标对象是 element、document、window,但也可以设定在其他如 XMLHttpRequest、AudioNode、 AudioContext 上。

了解什麽是监听事件後,就来研究语法吧!

绑定监听事件 AddEventListener

EventTarget.addEventListener(event, eventHandler, boolean)

第一个参数 Event

内建的监听事件很多,像是滑鼠的点击、移动、聚焦,各种使用者在浏览器上可以进行的行为都有对应的事件,详细可以到 MDN 列出的表格查看

与旧式事件绑定写法不同,事件名称不需要加上 on
ex. 点击事件写在 html 是 onclick,但在事件监听器是 click

第二个参数 Event Handler

事件触发後要执行的程序,可以是匿名或具名函式。

第三个参数 决定 捕获 Capturing | 冒泡 Bubbling

第三个参数为 boolean 值,决定监听事件是要绑定在捕获阶段还是冒泡阶段上。

  • false: 预设值,表示将监听事件绑定在 冒泡阶段 Bubbling Phase
  • true:表示将监听事件绑定在 捕获阶段 Capturing Phase

详细的解释推荐看这篇 事件回力镖 - 捕获与冒泡,接下来让我用变色圈圈告诉你差别~

实作:大中小圈圈变色方向

设置三个分别为大中小的圈圈,每个圈圈绑定点击时会亮起各自的背景色,大概的 html 阶层如下。
变色上为了让传递的效果明显一点,加上 setTimeout 设定时间差异,但以下解释先省略这部分,主要介绍绑定在冒泡阶段与绑定在捕获阶段的差异。

// 圈圈层层包裹
  <div class='big'>
    <div class='middle'>
      <div class='small'></div>
    </div>
  </div>

Bubbling 冒泡传递

将点击事件绑定在冒泡阶段

// 绑定事件的第三个参数都设为 false 
bigCircle.addEventListener("click", changeBlue, false);  // 点击大圈圈背景变深蓝 
middleCircle.addEventListener("click", changePurple, false); // 点击中圈圈背景变紫色
smallCircle.addEventListener("click", changeLightblue, false); // 点击小圈圈背景变浅蓝

动作:点击小圈圈
结果:小圈圈先亮 -> 中圈圈亮 -> 大圈圈亮

可以看到冒泡阶段的传递方向,是由内层的标签一路往外传,当小圈圈收到点击时,会再往外传到中圈圈,中圈圈再往外传到大圈圈,一直到最外层的 window 为止。

Carturing 捕获传递

将点击事件绑定在捕获阶段

// 绑定事件的第三个参数都设为 false 
bigCircle.addEventListener("click", changeBlue, true);  // 点击大圈圈背景变深蓝 
middleCircle.addEventListener("click", changePurple, true); // 点击中圈圈背景变紫色
smallCircle.addEventListener("click", changeLightblue, true); // 点击小圈圈背景变浅蓝

动作:点击最小圈圈
结果:大圈圈先亮 -> 中圈圈亮 -> 小圈圈亮

顺序跟刚刚不同!因为捕获阶段的顺序是从最外层的标签传到最内层,所以大圈圈会先经历捕获阶段,因此先捕捉到点击事件亮起背景色,而小圈圈是整个捕获阶段的终点,最後才收到点击事件。

Reference

重新认识 JavaScript: Day 15 隐藏在 "事件" 之中的秘密
DOM 的事件传递机制:捕获与冒泡
MDN

结语

所以罗,可以透过传递的方向差异制造不同的效果,一开始的灯泡就是将点击事件阶段绑定在 捕获阶段 capturing phase,所以当点击灯泡时,黑色灯光是从外暗到内!
每次学到新的语法就迫不及待试试可以做出什麽效果,觉得开心 ≧ω≦


<<:  TypeScript | Type 研究心得纪录 1

>>:  D25 / 为什麽 State 改变会触发 recomposition - State & Snapshot system

Flutter基础介绍与实作-Day22 旅游笔记的实作(3)

我们今天要接续昨天的划分4个区域开始,我们今天先从北部开始吧! 一样先来建立资料夹 lib/scar...

Day29 - GitLab CI 如何让工作流程流水线跑快一点?之三 让 Runner 执行更快一点

上一篇谈到从 .gitlab-ci.yml 开始建立关卡及工作,而後依序分派到工作伫列,等待 Git...

那些被忽略但很好用的 Web API / Clipboard

CTRL + C & CTRL + V,两个指令就能让你成为工程师。 Selection ...

【day11】争厚厚切牛排

位於南港车站附近的争厚厚切牛排 也是我们常去的口袋名单之一 平日营业时间是两段式的 但像今天周日的话...

React和DOM的那些事-节点新增算法

点击进入React源码调试仓库。 本篇是详细解读React DOM操作的第二篇文章,文章所讲的内容发...