了解冒泡和捕获之前,先要了解什么是事件和事件流
事件 :事件是可以被JS检测到的行为,当我们与页面交互时,事件就会产生
事件流 :触发事件会产生事件流,单个元素受到影响后会传播给其他元素,事件流描述的是页面中接受事件的顺序,分为冒泡和捕获
冒泡
一个子元素触发事件后,事件会从该子元素起一层一层向上传播,从下往上
graph BT
div --> body --> html --> document
捕获
一个子元素触发事件后,事件会从最顶层父级一层一层向下传播,从下往上
graph TB
document --> html --> body --> div
三种事件监听函数下的事件流
1.直接在html
中定义事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <style> #father{ margin: 20px auto; width: 200px; height: 200px; background-color: blue; } #son{ width: 100px; height: 100px; background-color: red; } </style>
<div id="father" onclick="console.log('father')"> //点击#father而不点击#son 只会输出father <div id="son" onclick="console.log('son')"> // 点击#son 依次输出son father,属于冒泡 </div> </div>
|
结论:直接在html
中定义事件只会冒泡
2.DOM0
级 事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <style> #father { margin: 20px auto; width: 200px; height: 200px; background-color: blue; } #son { width: 100px; height: 100px; background-color: red; } </style>
<div id="father"> //点击#father而不点击#son 只会输出father <div id="son"></div> // 点击#son 依次输出son father,属于冒泡 </div>
<script> father.onclick = function () { console.log("father"); }; son.onclick = function () { console.log("son"); }; </script>
|
结论:dom0
只会冒泡
html行内绑定事件和dom0级别一样
3.DOM2
级 事件
dom2
级格式为 el.addEventListener('click',fn,false)
其中 dom2
级第三个默认 false
,改为 true
就变为事件捕获。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <style> #father { margin: 20px auto; width: 200px; height: 200px; background-color: blue; } #son { width: 100px; height: 100px; background-color: red; } </style>
<div id="father"> <div id="son"></div> </div>
<script> father.addEventListener( "click", () => { console.log("father"); }, true ); son.addEventListener( "click", () => { console.log("son"); }, true ); </script>
|
都是 true
的时候,father 和 son 都是捕获,输出father son,点击father 只输出 father
都是 false
的时候,father 和 son 都是冒泡,输出son father,点击father 只输出 father
father 事件监听函数参数为 true
, son 事件监听函数参数为 false
时,father 为捕获,son 为冒泡,输出father son,点击father 只输出 father
father 事件监听函数参数为 false
, son 事件监听函数参数为 true
时,son为捕获,father为冒泡,输出son father,点击father 只输出 father
总结:
事件流的模型是自上而下捕获,到达目标,然后再自下而上冒泡。就像小球从空中落地再弹起。
1.事件捕获阶段
2.处于目标阶段
3.事件冒泡阶段