事件代理是什么?有哪些应用场景?

一、是什 么

事件代理,通俗的来讲,就是把一个元素的响应事件(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.getElementByTagName('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')

//事件委托,添加的子元素也有事件
oUl.onclick = function(ev){
	const 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 这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值