1. 介绍
又名事件代理,利用事件的冒泡机制,以及事件对象中可以准确获知触发事件元素的属性,将多个使用相同事件进行类似操作的子元素的事件处理函数委托给父元素绑定的现象。
意义:
- 减少重复性绑定的事件处理函数,减少内存占用
- 新添加的子元素也能拥有事件
2. 问题场景
情景:有一组列表,不论子元素个数,要求点击列表项让其中的文字变红
<ul>
<li>li_1</li>
<li>li_2</li>
<li>li_3</li>
<li>li_4</li>
<li>li_5</li>
<li>li_6</li>
</ul>
通常的做法是获取页面上左右 li 元素,然后遍历添加点击事件:
var lis = document.querySelectorAll("li");
for(var i = 0; i < lis.length; i ++){
lis[i].onclick = function (){
this.style.color = "#f00";
}
}
上例有6个 li 元素,需要绑定 6 次点击事件,如果换成100个,或者更多个,绑定需要占用的内存资源也就越多。同时如果我们给列表新添加 li 元素,新添加的元素不会有事件:
var liEle = document.createElement("li");
liEle.innerText = "li_" + (ulEle.children.length + 1);
ulEle.append(liEle);
liEle.click(); // li_7的颜色不会变红
这是因为获取 li 元素数组时,新添加的元素不在其中,并没有给它绑定事件,因此我们需要单独给新添加的元素绑定事件,如果绑定之后在添加呢?麻烦了。。。
3. 事件委托解决问题
var $ul = $('ul');
// 相当于就是 委托 ul元素,监听后代元素 li的点击操作
// 当点击 li元素时, 就会触发该事件处理程序
$ul.on('click','li',function(){
// 这里的this就指向 点击的li元素
this.style.color = '#f00';
})
$ul.append(`<li>li_新增</li>`);
// 新追加的 li元素 也会具备该点击事件