1.事件流定义
事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。
事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。
捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
2.举个栗子
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>事件流</title> 6 <style> 7 div{width: 300px;height: 300px;background: darkcyan;} 8 section{width: 200px;height: 200px;background: orange;} 9 p{width: 100px;height: 100px;background:tomato;} 10 </style> 11 </head> 12 <body> 13 <div id="grandfather"> 14 爷爷 15 <section id="father"> 16 爸爸 17 <p id="son">儿子</p> 18 </section> 19 </div> 20 </body> 21 <script> 22 var grand = document.getElementById('grandfather'), 23 father = document.getElementById('father'), 24 son = document.getElementById('son'); 25 son.onclick = function(){ 26 alert('son'); 27 } 28 father.onclick = function(){ 29 alert('father'); 30 } 31 grand.onclick = function(){ 32 alert('grand'); 33 } 34 35 </script> 36 </html>
执行结果如下:(先后弹出son,father,grand界面)
在冒泡型事件流中click事件传播顺序为div=>body=>html=>document
在捕获型事件流中click事件传播顺序为document=>html=>body=>div
如图:
注意:
注意:
1、所有现代浏览器都支持事件冒泡,但在具体实现中略有差别:
- IE5.5及更早版本中事件冒泡会跳过<html>元素(从body直接跳到document)。
- IE9、Firefox、Chrome、和Safari则将事件一直冒泡到window对象。
2、IE9、Firefox、Chrome、Opera、和Safari都支持事件捕获。尽管DOM标准要求事件应该从document对象开始传播,但这些浏览器都是从window对象开始捕获事件的。
3、由于老版本浏览器不支持,很少有人使用事件捕获。建议使用事件冒泡。
DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
事件捕获阶段:实际目标(<div>)在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到<html>再到<body>就停止了。
处于目标阶段:事件在<div>上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。
冒泡阶段:事件又传播回文档。
DOM2级事件 addEventListener() 和 removeEventListener()是用来分配和删除事件的函数。 这两个方法都需要三个参数,分别为:事件名称(String)、要触发的事件处理函数(Function)、指定事件处理函数的时期或阶段(boolean)。
由上图可知,捕获过程要先于冒泡过程。
第三个参数就是是否支持事件捕获,true支持事件捕获,false支持事件冒泡。