前言
看到一个问题:
addEventListener在removeListener会不会造成内存泄漏?
理解addEventListener事件监听和 removeListener移除事件监听,想一想如何更好的回答这个问题, 那么从最基础的深入去学习理解一遍之后再做解答。 于是乎,拿出JavaScript红宝书:JavaScript高级程序设计,一起来学习什么是事件。
思考理解
- 理解事件流
- 事件冒泡
- 事件捕获
- DOM事件流
Javascript与HTML的交互是通过事件实现的,事件代表文档或浏览器窗口中某个有意义的时刻,可以使用仅在事件发生时执行的监听器 订阅事件。
事件流
概念:事件流描述了页面接受事件的顺序。
但是IE和Netscape开发团队提出了完全相反的事件流方案:
- IE将支持降事件冒泡流
- Netscape communicator将支撑事件捕获流。
事件冒泡
概念: 事件开始的时候,由最具体的元素接受, 然后逐级向上传播到较为不具体的节点。
IE事件流被称为:事件冒泡,因为事件被定义为:从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。
例如:
<!DOCTYPE html>
<html>
<head>
<title> Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
点击页面中的
<div>➡️ 2 <body> ➡️ 3<html> ➡️ 4 document
所有现代浏览器都支持事件冒泡,只是在实现方式上会有一些变化。IE5.5及更早版本会跳过元素(从body元素直接到document)。 现代浏览器中的事件会一直冒泡到window对象。
事件捕获
概念:事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了在事件到达最终目标前拦截事件。
上述例子中,点击
document ➡️ 2<html> ➡️ 3 <body> ➡️ 4 <div>
虽然这是Netscape Communicator唯一的事件流模型,但事件捕获得到了所有现代浏览器的支持。实际上,所有浏览器都是从window对象开始捕获事件,而DOM2 Events规范规定的是从document开始
DOM事件流
DOM2 Events 规范规定事件流分为3个阶段:
- 事件捕获:事件捕获最先发生,为提前拦截事件提供了可能
- 到达目标:其次,实际的目标元素接收到事件。
- 事件冒泡:最后一个阶段冒泡,最迟要在这个阶段响应事件。
在DOM事件流中,实现的目标(div元素) 在捕获阶段不会接收到事件。是因为捕获阶段从 document到 html再到body就结束了。
下一阶段,就会在div元素上触发事件的“到达目标”阶段,通常在事件处理时被认为是冒泡阶段的一部分。然后,冒泡阶段开始,事件反向传播至document。
参考阅读: 《JavaScript高级程序设计》