什么是事件捕获与事件冒泡
引用图片说明一下:
DOM树是浏览器解析html文件生成的树结构,当事件在节点上产生时,以节点 <a> 为例:
- 当节点 <a> 产生事件cilck时,事件从document节点开始向下捕获,依次经过html、body、p最终捕获a的cilck事件
- a的cilck被捕获后,事件沿捕获路径原路返回,依次经过p、body、html节点
事件冒泡与事件的Web API
一般使用EventTarget接口的addEventListener()函数绑定dom事件,来看看该函数的语法:
EventTarget.addEventListener(event, function, useCapture);
参数释义
event:事件,包括cilck、mousemove等
useCapture:缺省为false,即不在捕获时触发
敲一下代码,不敲不知道,敲了发现自己前端已经忘得差不多了
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>事件捕获与冒泡</title>
</head>
<body>
<div id="scenic"></div>
</body>
<script>
const divNum=15;
function render(callback){
var div="";
for(var i=divNum;i>=1;i--){
var divstyle="style='position:absolute;top:50px;width:100%;height:50px;background-color:#"+(0xFFFFFF-i*0x010101)+"'";
div="<div id='div"+i+"' "+divstyle+">"+div+"<p>"+i+"</p></div>";
}
document.getElementById("scenic").innerHTML=div;
callback();
}
function addListener(){
for(var i=1;i<=divNum;i++){
let divId="div"+i;
document.getElementById(divId).addEventListener("click",function(){
console.log(divId+":捕获");
},true);
document.getElementById(divId).addEventListener("click",function(){
console.log(divId+":冒泡");
},false);
}
}
window.onload=function (){
render(addListener);
}
</script>
</html>
运行单击div5,控制台输出:
相关函数:
1. 移除事件绑定
API:
evenTarget.removeEventListener(type, listener[,useCapture]);
如果同一个组件同时注册了事件捕获与事件冒泡监听,需要使用useCapture指定移除,该参数缺省为false。
2. 阻断事件监听
API有两种:
even.stopPropagation();
相较stopPropagation(),stopImmediatePropagation()还能阻断同名事件监听
even.stopImmediatePropagation();
2.1事件捕获时触发阻断
DOM0事件绑定:
<button οnclick="log(event)">ac</button>
<script>
function log(event) {
console.log("cilck");
event.stopPropagation();
}
</script>
在ECMAScript6中已经淘汰了event关键字
DOM2事件绑定:
document.getElementById("div5").addEventListener("click",function (event){
event.stopPropagation();
},true);
2.2. 事件冒泡时触发阻断
document.getElementById("div5").addEventListener("click",function (event){
event.stopPropagation();
});