JavaScript——事件委派之详解

本文深入解析事件委派原理,对比传统事件绑定,展示如何利用事件委派提高代码性能,支持动态元素事件绑定,适用于前端开发人员提升技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在看代码之前,我们先来了解一下什么叫事件委派。

事件委派的定义就是,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素。

换句话说,就是把一个本来让下属干的事情交给上司做了。

比如说,鼠标点击事件,本来页面上有很多的鼠标点击事件,需要一个个的去写实现函数,但是如果你把鼠标点击事件交个上司来完成,那么就是你鼠标点击那里的时候,就相当于上司找对应的下属来完成此事件,而不像前面的一个个的去找实现函数。很简单的例子就是给ul中的li加事件:

<ul id="ul1" >
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>


如果给每个li添加点击事件,:

var li=document.getElementsByTagName('li');
function A(){
    alert(li.innerHTML);
};
li.click=A;

上面的代码alert(li[i].innerHTML)每次运行时都需要 查询li[i].innerHTML的值,且为每一个li都添加了点击事件,这显然会影响代码性能。

这样做有两个很明显的弊端:

1.很耗费资源,因为这种方式是给每个li都加上了事件,li的个数少的话还没事,如果li多的话会很耗费资源。

2.如果后期动态添加li,不会拥有这个弹出事件。

针对以上问题,可以用事件委派来解决。

我们换做事件委托来看看。

var ul=document,getElementById('ul1')
var target = ul.target || ul.srcElement; //兼容处理
alert(target.innerHTML);


这样做的好处就是不在进行查询,减少了DOM操作,极大地改善了代码性能。

如果大家对于事件委派可改善性能这一点不太明白,可以看看下面两个例子:

如果大家不是很好理解,下面给大家提供几个例子:

例子一:

<ul id="ul">
    <li>000001</li>
    <li>000002</li>
    <li>000003</li>
  </ul>
  <script type="text/javascript">
    var ul = document.getElementById('ul');
    var li = ul.getElementsByTagName('li');
    //用事件委托,通过li的父元素ul,给li添加点击事件
    ul.onmouseover = function (event) {

    // event对象用于存储事件的数据,例如触发事件的元素、鼠标的位置及状态、按下的键等等;
    // event对象只在事件发生的过程中才有效。
    // firefox跟IE使用的event的方法不同,IE的event是全局变量,随时可用;firefox需要在事件方法的参数里写event才能用,是运行时的临时变量。
    // 在IE/Opera中是window.event,在Firefox中是event;

     var event = event || window.event; //event对象
     var target = event.target || event.srcElement; //onmouseover事件的调用者
     if (target.nodeName.toLowerCase() == 'li') { // onmouseover事件的调用者的DOM元素标签名
       target.style.background = 'red';
     }
    }
    ul.onmouseout = function (event) {
      var event = event || window.event;
      var target = event.target || event.srcElement;
      if (target.nodeName.toLowerCase() == 'li') {
        target.style.background = '';
      }
    }
  </script>

例子二:


<ul id="resources">  
	<li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>  
	<li><a href="http://sitepoint.com">Sitepoint</a></li>  
	<li><a href="http://alistapart.com">A List Apart</a></li>  
	<li><a href="http://yuiblog.com">YUI Blog</a></li>  
	<li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>  
	<li><a href="http://oddlyspecific.com">Oddly specific</a></li>  
</ul> 
<script>
	//事件委派1
	(function(){  
		var resources = document.getElementById('resources');  
		var links = resources.getElementsByTagName('a');  
		var all = links.length;  
		
		for(var i=0;i<all;i++){  
			links[i].addEventListener('click',handler,false);  
		};  
		
		function handler(e){  
			var x = e.target; // Get the link that was clicked  
			alert(x);  
			e.preventDefault();  
		};  
	})(); 
	//利用事件委派可以写出更加优雅的
	(function(){  
		var resources = document.getElementById('resources');  
		resources.addEventListener('click',handler,false);  
		
		function handler(e){  
			var x = e.target; // get the link tha  
			if(x.nodeName.toLowerCase() === 'a'){  
				alert(x);  
				e.preventDefault();  
			}  
		};  
	})();  
</script>

好了,我们继续讲下面的话题。

上面说到,后期动态增加li不会弹出事件,那么事件委托怎么样?

对于事件委托这位人名币玩家,动态添加的元素,也会被绑定li该有的事件。
 

 <input type="button" id="btn" value="添加li">
 <ul id="ul">
   <li>111111</li>
   <li>22222</li>
   <li>33333</li>
 </ul>
  <script type="text/javascript">
    //获取元素
    var ul = document.getElementById('ul');
    var btn = document.getElementById('btn');
    //鼠标覆盖
    ul.onmouseover = function (event) {
      var event = event || window.event;
      var target = event.target || event.srcElement;
      if (target.nodeName.toLowerCase() == 'li') {
        target.style.background = 'red';
      }
    }
    //鼠标离开
    ul.onmouseout = function (event) {
      var event = event || window.event;
      var target = event.target || event.srcElement;
      if (target.nodeName.toLowerCase() == 'li') {
        target.style.background = '';
      }
    }
    //点击添加li按钮
    btn.onclick = function () {
      var lisLength = ul.getElementsByTagName('li').length;
      var newLi = document.createElement('li');
      newLi.innerHTML = 11111*(lisLength+1);
      ul.appendChild(newLi);
    }
  </script>

很显然,使后期添加的li也具有同样的功能,这是普通事件做不到的。我们可以用事件委派来为动态添加的元素添加事件。
所以说,在对元素进行事件绑定的时候,推荐使用事件委派,它既可以为动态添加的元素附上效果,也可以改善代码性能,何乐而不为呢~

事件委派乍一看好像很难,但是多试几个例子,就能够理解啦。

大家还在等什么?快去试试吧~

Biu~~~~我先去也~~
 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值