以下大部分为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。
目录:
1. 事件冒泡
2. 事件捕获
3. DOM事件流
Q:什么是事件?
A:事件是文档或浏览器窗口中发生的一些特定的交互瞬间。
Q:事件能够实现什么?
A: 1. 事件能够实现 JS 与 HTML 之间的交互
2. 事件可以作为分担服务器运算负载的一种手段
Q:事件的实现方式?
A:可以使用侦听器(或处理程序)来预订之间,以便事件发生时执行相应的代码。这种模式被称为观察者模式。
Q:什么是事件流?
A:事件流描述的是从页面中接收事件的顺序。但是,IE的事件流是事件冒泡流,Netscape Communicator的事件流是事件捕获流。
Q:什么是事件冒泡(event bubbling)?
A:事件冒泡是事件开始时由最具体的元素(文件中嵌套层次最深的那个节点)接收,然后逐级向上传播到较不具体的节点(文档)。
Q:所有浏览器都支持事件冒泡吗?具体实现都一样吗?
A:都支持。具体实现有差别,差别体现在IE5.5及更早版本的事件冒泡会跳过<html>元素,IE、Safari、Chrome 和 Firefox则将事件一直冒泡到 window 对象。
下面举个栗子。点击了页面中的 div 元素后页面中的 click 事件会按照如下顺序传播:<div> 👉 <body> 👉<html> 👉document
DOM树:
click 事件传播顺序:
Q:事件捕获的思想是什么?
A:不太具体的节点更早接收到事件,最具体的事件最后接收到事件。
Q:事件捕获的用意是什么?
A:在事件到达预定目标之前捕获它。
Q:事件捕获的具体实现?
A:"DOM2级"事件规范要求应该从 document 对象开始传播,但IE、Safari、Chrome、Opera 跟 Firefox 都是从 window 对象开始捕获事件的。
Q: 所有版本的浏览器都支持事件捕获吗?
A:不,老版本浏览器不支持。所以很少使用事件捕获,可以放心地使用事件冒泡。
举个事件捕获的例子,以上面事件冒泡的 HTML 页面为例。点击了页面中的 div 元素后页面中的 click 事件会按照如下顺序传播:document 👉 html 👉body 👉div
click 事件传播顺序:
"DOM2级事件"规定的事件流包括3个阶段:1. 事件捕获阶段 2. 处于目标阶段 3. 事件冒泡阶段
各个阶段完成的工作:
事件捕获阶段 : 为截获事件提供机会
处于目标阶段 : 实际的目标接收到事件
事件冒泡阶段 : 对事件做出响应
以前面的 HTML 页面为例,click 事件触发顺序为:
事件捕获阶段:图中①②③。实际的目标(<div>元素)在捕获阶段不会接收到目标。虽然 “DOM2级”事件规范明确要求捕获阶段不涉及时间目标,但IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。
处于目标阶段:图中④。事件在<div>上发生,并且在事件处理中被看成是冒泡阶段的一部分。
事件冒泡阶段:图中④⑤⑥⑦。
注意:
支持 DOM 事件流的浏览器:IE9、Opera、Firefox、Chrome、Safari
不支持 DOM 事件流的浏览器:IE8及更早版本
加深理解 DOM 事件流
利用 addEventListener 方法举个例子,可以通过设置该方法的第三个参数来设置在捕获阶段还是在冒泡阶段调用事件处理程序。
事件传播顺序:document -> html -> body -> div -> input -> div -> body -> html -> document
全部事件处理程序在冒泡阶段被调用
点击按钮后,调用事件处理程序顺序:input -> div -> body
事件传播顺序:document -> html -> body -> div -> input -> div -> body -> html -> document
全部事件处理程序在捕获阶段被调用
点击按钮后,调用事件处理程序顺序:body -> div -> input
事件传播顺序:document -> html -> body -> div -> input -> div -> body -> html -> document
有的事件在捕获阶段被调用,有的事件在冒泡阶段被调用
点击按钮后,调用事件处理程序顺序:body-> input -> div
事件传播顺序:document -> html -> body -> div -> input -> div -> body -> html -> document