什么是事件托管/事件委托
利用 事件冒泡 原理,只指定 一个事件处理程序,就可以管理 同一类型 的所有事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ol id="ol">
<li>目标一</li>
<li>目标二</li>
<li>目标三</li>
<li>目标四</li>
<li>目标五</li>
<li>目标六</li>
<li>目标七</li>
<li>目标八</li>
<li>目标九</li>
<li>目标十</li>
</ol>
<script type="text/javascript">
//不使用事件托管
var li=document.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].addEventListener("click",function () { //10个li的“click”事件,需要10个事件监听器,分配10份内存;
this.style.backgroundColor = "yellowgreen";
});
}
//利用事件冒泡原理,在ol上代理所有li的“click”事件
var ol = document.getElementById("ol");
ol.addEventListener("click",function (e) {
if(e.target.parentNode==this){ //e.target点击到的元素,this为事件绑定的元素(ol),
//判断点击到的元素(目标一~目标十)的父节点是不是ol,防止触发父级元素的点击事件
e.target.style.backgroundColor = "yellowgreen";
console.log(e.target.innerHTML);
}
})
</script>
优点
减少事件注册,节省内存。例如上面代码,只指定 ol的处理程序,即可管理所有所有li的“click”事件;
简化了dom节点更新时,相应事件的更新。
- 缺点
利用事件冒泡的原理,不支持不冒泡的事件;
层级过多,冒泡过程中,可能会被某层阻止掉。
理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在ol上代理li,而不是在document上代理li。
把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。