14. 解释 Event bubbling & Event delegation

Event Bubbling


定义

Event bubbling跟操作DOM元素的事件有关,是指当子元素(child)和父元素(parent)在监听相同类型的事件(event)时,事件的执行会往该元素的父层传递。

描述依然很抽象,所以要继续看例子:

示例

codepen范例程序码

// HTML
<div class="parent">
  <div class="child"></div>
</div>
// javaScript
const parent = document.querySelector(".parent");
const child = document.querySelector(".child");

parent.addEventListener("click", () => {
  console.log(`parent event`);
});

child.addEventListener("click", () => {
  console.log("child event");
});

范例的结构,是由一个父元素的<div>包裹一个子元素<div>
而父元素和子元素都加上"click event"的监听器。

在点击父元素的区块时,console会输出"parent event"

// output:
"child event"

然而,在点击子元素的区块时,console会依序输出"parent event"

// output:
"child event"
"parent event"

也就是说,如果子元素和父元素被绑上了一样的监听事件("click")

浏览器在执行完子元素的事件後,会继续向上执行父元素的事件。

(可以想像事件发生的顺序会像泡泡一样上浮,表示事件向上传递。)

如果想要避免这样的情形,可以使用 event.stopPropagation()方法:

const parent = document.querySelector(".parent");
const child = document.querySelector(".child");

parent.addEventListener("click", () => {
  console.log(`parent event`);
});

child.addEventListener("click", (e) => {
  console.log("child event");
  e.stopPropagation();
});

范例在子元素里加入event.stopPropagation(),这样在点击子元素时,就不会再继续触发父元素的事件,也就可以防止Event Bubbling的行为发生。

Event Delegation


delegation有委派的意思,所以直译是指事件委派。
而Event delegation是一种利用Event bubbling的性质,去委派事件的一种方式。

但是,是谁要把事件委派给谁呢?这就是接下来要看的例子:
codepen范例程序码

// HTML
<div class="parent">
  <div class="child child1"></div>
  <div class="child child2"></div>
  <div class="child child3"></div>
</div>
// javaScript
const parent = document.querySelector(".parent");

parent.addEventListener("click", () => {
  console.log("We did the same event!");
});

这次的结构让外层的<div>包了三个区块!

而在这段程序码里,不管点击的是父元素或子元素的<div>
他们都会执行一样的结果:

// output:
"We did the same event!"

也就是说,
→假设我们今天要指派一样的事件给很多元素,可以利用Event bubbling会传递事件的性质用一个父元素将所有的元素包起来,将事件委派给父元素,就可以让所有的child都执行相同的工作!

【如内文有误还请不吝告知>< 谢谢阅览至此的各位:D】

参考资料:
Introduction to events - Learn web development | MDN
[教学] 浏览器事件:Event Bubbling, Event Capturing 及 Event Delegation | Shubo 的程序教学笔记

-----正文结束-----


<<:  [Day0] 前言

>>:  Day 15 -New Project的开始

[Day 23] 撰写我们的第一个 test double

回到我们的目标 我们希望能测试 updateUsersTags(),传入参数 filter时,会执行...

【Day 27】关於 Deno 以及基础安装

关於 Deno Deno 上一次调整後,为了效能问题,将核心模块从 Typescript 改回 J...

Day8:结构化并发 (Structured Concurrency)

还记得我们第一个 Coroutine 程序吗? suspend fun showContents()...

[区块链&DAPP介绍 Day3] 什麽是智能合约

今天来聊聊我们接下来的27天会环绕的议题,就是智能合约(samrt contract)。 智能合约(...

C# delegate

我们习惯把数据或者对像作为参数传递给方法,比如: int i = int.Parse("9...