详解事件代理(事件委托)以及应用场景

事件代理(也称事件委托)事件代理,俗地来讲,就是把⼀个元素响应事件 ( 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('the content is: ', target.innerHTML);
 }
};
//添加新节点
oBtn.onclick = function () {
 num++;
 const oLi = document.createElement('li');
 oLi.innerHTML = `item ${num}`;
 oUl.appendChild(oLi);
};

可以看到,使⽤事件委托,在动态绑定事件的情况下是可以减少很多重复⼯作的

总结:

 适合事件委托的事件有: click mousedown mouseup keydown keyup keypress 从上⾯应⽤场景中,我们就可以看到使⽤事件委托存在两⼤优点:

  • 减少整个⻚⾯所需的内存,提升整体性能
  • 动态绑定,减少重复⼯作

但是使⽤事件委托也是存在局限性:

  • focus blur 这些事件没有事件冒泡机制,所以⽆法进⾏委托绑定事件
  • mousemove mouseout 这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位, 对性能消耗⾼,因此也是不适合于事件委托的

如果把所有事件都⽤事件代理,可能会出现事件误判,即本不该被触发的事件被绑定上了事件

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值