事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。
例如,click事件冒泡到document。这意味着可以为整个页面指定一个onclick事件来处理事件程序,而不用为每个可点击元素分别指定事件处理程序。
<ul id="myLinks">
<li id="goSomewhere">Go Somewhere</li>
<li id="doSomething">Do Something</li>
<li id="sayHi">Say Hi</li>
</ul>
通常的做法:
let item1 = document.getElementById("goSomewhere")
let item2 = document.getElementById("doSomething")
let item3 = document.getElementById("sayHi")
item1.addEventListener("click",(event) => {
location.href = "xxx";
});
item2.addEventListener("click",(event) => {
document.title = "I changed the document's title";
});
item3.addEventListener("click",(event) => {
console.log("hi");
});
使用事件委托,只要给所有元素共同祖先节点添加一个事件处理程序,就可以解决问题
let list = document.getElementById("myLinks");
list.addEventListener("click",(event) => {
let terget = event.target;
switch(targetr.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
locetion.href = "xxx";
break;
case "sayHi":
console.log("hi");
break;
}
});
这里只给<ul id="myLinks">
元素添加了一个onclick事件处理程序。
因为所有列表项都是这个元素的后代,所以它们的事件会向上冒泡,最终都会由这个函数来处理。但事件目标是每个被点击的列表项,只要检查event对象的id属性就可以确定,然后再执行相应的操作即可。
相对于前面不使用事件委托的代码,使用事件委托的代码不会导致先期延迟,因为只访问了一个DOM元素和添加了一个事件处理程序。
事件委托有以下优点:
- document对象随时可用,任何时候都可以给它添加事件处理程序(不用等待DOMContentLoaded或load事件)。
- 节省花在设置页面事件处理程序上的时间。只指定一个事件处理程序既可以节省DOM引用,也可以节省时间。
- 减少整个页面所需的内存,提升整体性能。