JavaScript事件代理

基本概念

事件代理(Event Delegation),又称为事件委托。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

举个例子就是宿舍6个人睡到中午到饭点了,一个方案是都起床去吃饭,另一个方案就是出一个幸运儿起床去把6个人的饭都买回宿舍(这个例子有点懒),然后分给每个人去吃。
这里买饭就是一个事件,每个人就是需要响应的元素,而幸运儿则是代理的元素,每个人都把这个事件委托给了这位幸运儿。

为什么要用事件委托呢?

在JavaScript中,在页面上的事件处理程序的数量将直接影响到页面的整体性能,因为事件处理需要不断的与dom节点进行交互,访问dom节点的次数越多,引起回流与重绘的次数也会越多,这样会延长整个页面的就绪时间。
如果使用事件委托,只对它的父级这一个对象进行操作,那么访问dom的操作就只有一次,这样就能大大减少与dom的交互次数,提高性能。
例如:对每个li都添加click操作和只对div添加click操作

<div>
	<ul>
		<li></li>
		<li></li>
		<li></li>
	</ul>
</div>

原理

事件委托的原理是利用事件冒泡的原理来实现的,事件冒泡:事件从最深的节点开始,然后逐步向上传播事件。还是上面的例子,给li添加一个click点击事件,那么这个事件就会开始向上传播,执行顺序为li>ul>div,那么给最外层的div加一个click点击事件,那么里面的li、ul做点击的时候,都会冒泡到最外层的div上,所以ul、li点击都会触发div的点击事件。这就是事件委托,委托父级元素代它们执行事件。

子元素实现点击事件需要:

<ul>
	<li>111</li>
	<li>111</li>
	<li>111</li>
</ul>
<script>
	var Ul = document.getElementByTagName("ul");
    var Li = Ul.getElementsByTagName('li');
    for(var i=0;i<Li.length;i++){
        Li[i].onclick = function(){
            alert(111);
        }
    }
</script>

当点击事件发生,首先要找到ul,然后遍历li,找到目标li的位置,才会执行操作。那么用事件代理呢?

<script>
	window.onload = function(){
    var Ul = document.getElementByTagName("ul");
   	Ul.onclick = function(){
        alert(111);
    }
}
</script>

这里当我们点击li时,事件为冒泡到ul上,ul上面的点击事件就会触发。这儿一个最大的问题就是点击ul的任何地方都会触发这个事件,不过这个可以用Event对象的属性target(返回事件的目标节点)来解决。标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名。这样改下就只有点击li会触发事件了,且每次只执行一次dom操作

<script>
	window.onload = function(){
  		var Ul = document.getElementByTagName("ul");
  		Ul.onclick = function(ev){
    		var ev = ev || window.event;
    		var target = ev.target || ev.srcElement;
    		if(target.nodeName.toLowerCase() == 'li'){
       		alert(111);
         	alert(target.innerHTML);
    		}
  		}
	}
</script>

当然,在使用事件代理的时候我们不需要考虑新增子元素的事件处理程序,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。
当然一些比如mouseover、mouseout等需要计算它们的位置的事件,使用事件代理就很不方便了,还有一些没有冒泡特性的事件也就更加不适合使用事件代理了。

那么当每个li需要实现的点击事件不一样呢?

扩展思考:

参考:https://www.cnblogs.com/linhongjie/p/12827017.html

以上纯属个人见解,有什么不对的地方还请指正,感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值