本篇文章给大家带来的内容是关于javascript事件委托的详细介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
事件委托(又名事件代理),就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
网上有关于事件委托的一个“取快递”例子,十分生动,这里我对它作一些修改和拓展,然后通过程序来说明事件委托的机制。
某公司有三位员工,他们的快递收件地址为公司,每当有快递送达时,快递员拨打其电话进行通知,他们接到电话后去取件。
员工id员工名称联系方式
a 甲 111111
b 乙 222222
c 丙 333333
对应到页面,就是每个员工是一个标记:<ul id="前台工作人员"> <li id="a">员工甲</li> <li id="b">员工乙</li> <li id="c">员工丙</li></ul>
每位员工接电话取快递的行为就是一个个事件,这里我们假设收取快递行为对应着onclick事件:
a.onclik = function() { 收取快递;};b.onclick = function() { 收取快递;};c.onclick = function() { 收取快递;};
以上的实现,通常为通过循环遍历每一个员工,为其增加事件:
/*程序1*/var aul = document.getelemengtbyid(前台工作人员);var ali = aul.getelemengtsbytagname(li);for (var i = 0; i < ali.length; i++) { ali[i].onclick = function() { 收取快递; }}
可以看到,为每个员工都设置一个事件,会产生冗余代码,占用内存,同时会进行多次dom操作(与dom节点进行交互),影响页面运行性能。
“减少dom操作是性能优化的主要思想之一”
于是,我们理所当然地想到:为什么不能让前台工作人员帮我们签收快递呢?
<ul id="前台工作人员"> <li id="a">员工甲</li> <li id="b">员工乙</li> <li id="c">员工丙</li></ul>/*程序2*/var tel = document.getelementbyid(前台工作人员);tel.onclick = function() { 收取快递;}
假设此时快递员打电话通知员工甲取件(onclick),但员工甲的dom节点<li>并无对应事件(onclick),所以这个事件会“冒泡”到<li>的父元素<ul>,发现<ul>上有onclick处理事件,于是触发该事件,由前台工作人员收取快递。
可以看到,这样一来,不仅缩减代码量,同时与dom节点的交互次数也得到了缩减。
还有一个优点:当增加新的dom节点时,自动携带父元素的事件效果。也就是说,当有一个新员工丁来公司后,前台工作人员会直接帮他收取快递,而无需专门为他设置事件。
例如,当新员工丁来到公司后:
...<input type="button" id="btn" value="添加新员工">....../*程序3*/var abtn = document.getelementbyid(btn);abtn.onclick = function() { var ali = document.createelement(li); oli.innerhtml = 员工丁; aul.appendchild(ali);}...
在不使用事件委托的程序中,新增的员工丁是没有事件的,我们需要用一个函数包含住程序1:
/*程序4*/function pro1() { var aul = document.getelemengtbyid(前台工作人员); var ali = aul.getelemengtsbytagname(li); for (var i = 0; i < ali.length; i++) { ali[i].onclick = function() { 收取快递; } }}
然后在新增新员工丁的程序的末尾执行这个函数:
/*程序5*/var abtn = document.getelementbyid(btn);abtn.onclick = function() { ... pro1();}
这样做的缺点是显而易见的:dom节点交互次数成倍增加。
若我们采用事件委托机制来实现,就不会存在这个问题,子元素节点的onclick事件会直接在父元素节点得到执行。
到这里,我们会想到:对于同一种事件来说,使用事件委托将其放置在父元素节点上固然很方便。但如果对于不同的子元素节点要执行不同的事件呢,还能使用事件委托吗?
答案是肯定的。
例如上述三位公司员工,总是使用固定品牌的快递:
员工甲因为便宜,喜欢使用申通快递,申通只送到园区大门;员工乙是京东会员,总是购买京东自营商品,京东快递送到楼下;员工丙是顺丰vip,顺丰快递会送到送到所在楼层大厅。他们三位在接到电话后,前台工作人员需要去不同的地方取件,对于不使用事件委托的程序,需要对每个人设置独特的处理事件:
var a = document.getelementbyid(a);var b = document.getelementbyid(b);var c = document.getelementbyid(c);a.onclick = function() { 去园区大门取快递;}b.onclick = function() { 去楼下取快递;}c.onclick = function() { 去本层大厅取快递;}
至少需要三次dom操作,而且为每一个对应节点都设置了事件函数。
而若采用事件委托:
var aul = document.getelemengtbyid(前台工作人员);aul.onclick = function (ev) { var target = ev || window.event; /*兼容浏览器*/ var target = ev.target || ev.srcelement; /*兼容浏览器*/ if (target.nodename.tolocalelowercase() == li) { switch(target.id) { case a : 去园区大门取快递; break; case b : 去楼下取快递; break; case c : 去本层大厅取快递; break; } }}
这样一来,dom操作就只有一次,其他的操作都在js内进行,可以有效提升网页性能。
以上便是js事件委托的基本思想。简而言之,就是利用事件冒泡这一特点,来对事件进行管理,减少冗余代码,减少不必要的创建,减少交互操作以节约内存和提高性能。
事件冒泡事件冒泡是当触发某个dom元素节点时,若该节点没有对应事件,则检查其父元素是否有对应事件,若有,则执行,若没有,继续向上检查。与其对应的还有事件捕获
以上就是javascript事件委托的详细介绍(附代码)的详细内容。