把一个元素响应事件(click、keydown…)的函数委托到另一个元素
事件流的都会经过三个阶段: 捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就是在冒泡阶段完成
事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数
很多人干同一件事件,变成推出一个人这件事件,
如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件
<ul id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
......
<li>item n</li>
</ul>
如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的
// 获取目标元素
const lis = document.getElementsByTagName("li")
// 循环遍历绑定事件
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function(e){
console.log(e.target.innerHTML)
}
}
这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
// 兼容性处理
var event = e || window.event;
var target = event.target || event.srcElement;
// 判断是否匹配目标元素
if (target.nodeName.toLocaleLowerCase === 'li') {
console.log('the content is: ', target.innerHTML);
}
});
也避免了动态添加和删除 绑定和解绑事件的繁琐
下面html结构中,点击input可以动态添加元素
<input type="button" name="" id="btn" value="添加" />
<ul id="ul1">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
使用事件委托
const oBtn = document.getElementById("btn")
const oUl = document.getElementById("ul1")
const num = 4;
// 事件委托,添加的子元素也有事件
oUl.onclick = function(ev){
ev = ev || window.event;
const target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase()=='li'){
console.log('is',target.innerHTML)
}
};
// 添加新节点
oBtn.onclick = function(){
const oLi = document.createElement("li");
oLi.innerHTML = `item ${num}`;
oUl.appendChild(oLi)
}
适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress
优点: