基本概念
事件代理,又称之为事件委托。是js中常用绑定事件的常用技巧。顾名思义:“事件代理”就是把原本需要绑定在子元素的响应事件(click、keydown.....)委托给父元素,让父元素担当事件监听的职务。事件代理的原理就是DOM元素的事件冒泡。
举个例子:
比如一个宿舍的同学快递同时到了,一种方法就是一个一个去取,还有一种方法就是把这件事情委托给宿舍长,让一个人去拿所有的快递,然后再根据收件人一一分发给每个宿舍同学。
在这里,去快递就是一个事件,每个同学指的是需要响应事件的DOM元素,而统一领取快递的宿舍长就是代理元素,所以真正绑定事件的就是这个元素,按照收件人分发快递的过程就是事件执行,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者那几个。
事件冒泡
一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播会分为三个阶段。
1、捕获阶段:从window对象传到目标节点称为“捕获阶段”,捕获阶段不会影响任何事件;
2、目标阶段:在目标节点上触发,称为“目标阶段”;
3、冒泡阶段:从目标节点传回window对象,称之为“冒泡阶段”。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定的外层;
事件委托的优点
【1】可以大量节省内存占用,减少事件注册,比如在ul上处理所有li的click事件。
<ul id = "list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
.........
<li>item 4</li>
</ul>
// ......代表中间还有未知数个li
如上图代码所示,如果给每个li列表项都绑定一个函数,那对内存的消耗是非常大的,因此最好的解决方法就是将li元素上的事件委托到父元素ul身上,执行事件时再去判定目标元素。
【2】可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
在很多时候,我们需要通过AJAX或者用户操作动态的增加或者删除列表项里元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件;
若使用事件委托就没有这种麻烦了,以为事件时绑定在父层的。
demo实现
【1】js原生实现事件委托
<ul id ="myUl">
<li id = "1">1</li>
<li id = "2">2</li>
<li id = "3">3</li>
</ul>
使用事件委托,只在DOM树中最高层次上添加一个事件处理程序。
var item1 = document.getElementById("1");
var item2 = document.getElementById("2");
var item3 = document.getElementById("3");
document.addEventListener("click", function (event) {
var target = event.target;
switch (target.id) {
case "1":
document.title = "事件委托";
break;
case "2":
location.href = "http://www.baidu.com";
break;
case "3": alert("hi");
break;
}
})
使用事件委托注意事项
使用“事件委托”时,并不是说把原生事件委托的元素越靠近顶层越好。事件冒泡的过程中也需要耗时,越靠近顶层,事件的“事件传播链”越长,也就越耗时。