目录
- 是什么
- 为什么
- 事件委托原理回顾
- 举例子
- 事件委托的优点
- 总结
是什么
利用 JS 事件冒泡动态为元素绑定事件的方法称为事件委托(Event Delegation,也称为“事件代理”)。
事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。
为什么
在 JavaScript 中,页面内事件处理程序的个数会直接影响页面的整体性能,因为每个事件处理程序都是对象,对象会占用内存,内存中的对象越多,页面的性能则越差。此外,事件处理程序需要与 DOM 节点进行交互,访问 DOM 的次数越多,引起浏览器重绘和重排的次数也就越多,从而影响页面的性能。
- 重绘是指当元素样式改变时,浏览器会根据元素的新样式重新绘制元素的外观。
- 重排是指当 DOM 树的一部分发生变化时(例如元素尺寸改变),浏览器会重新创建 DOM 树。
事件委托原理回顾
事件委托是利用事件的冒泡原理来实现的,大致可以分为三个步骤:
- 确定要添加事件元素的父级元素
- 给父元素定义事件,监听子元素的冒泡事件
- 使用 event.target 来定位触发事件冒泡的子元素。
e.target指向的是触发事件的元素; e.currentTarget指向的是添加监听事件的元素;
注意:使用事件委托时,并不是说把事件委托给随意一个父元素就行。因为事件冒泡的过程也需要消耗时间,距离越远,所需的时间也就越长,所有最好在直接父元素上使用事件委托。
举例子
1.假如我们要为 ul 列表下的每个 li 标签添加点击事件,如果不使用事件委托,最简单的办法就是使用循环来为每个 li 标签绑定事件,示例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JavaScript</title> </head> <body> <ul id="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <script> window.onload = function(){ var the_ul = document.getElementById('list'); var the_li = the_ul.getElementsByTagName('li'); for( var i=0; i < the_li.length; i++ ){ the_li[i].onclick = function(){ console.log(this.innerHTML) } } } </script> </body> </html>
2.通过上面的代码可以看出,要为每个 li 标签绑定点击事件,首先需要找到 ul 标签,然后通过 ul 标签找到所有 li 标签, 最后在通过遍历所有 li 标签来绑定事件。若使用事件委托的话,就会简单很多,示例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JavaScript</title> </head> <body> <ul id="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <script> window.onload = function(){ var the_ul = document.getElementById('list'); the_ul.onclick = function(e){ console.log(e.target.innerHTML) } } </script> </body> </html>
通过代码可以看出,使用事件委托我们只需要为 ul 标签绑定事件,当 li 标签被点击时,由于事件冒泡的特性,会触发 ul 标签上的事件,我们只需要在事件中通过 event 对象中的 target 属性来找到被点击的 li 标签即可。不过这样做也有一个弊端,那就是当我们点击 ul 标签时,也会触发事件。
3.另外,如果我们需要动态的向 ul 标签中添加 li 标签,同时也需要在新添加的 li 标签中添加点击事件,就必须通过事件委托来实现了,示例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JavaScript</title> </head> <body> <ul id="list" style="width: 100px;margin:0;float: left;"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <button style="float:left;" id="addli">添加一个 li</button> <button style="float:left;" id="delli">删除一个 li</button> <script> window.onload = function(){ var the_ul = document.getElementById('list'); var the_li = the_ul.getElementsByTagName('li'); var sum = the_li.length the_ul.onclick = function(e){ console.log(e.target.innerHTML) }; document.getElementById('addli').onclick = function (){ var newli = document.createElement("li"); newli.innerHTML = ++sum; the_ul.appendChild(newli); }; document.getElementById('delli').onclick = function (){ the_ul.firstElementChild.remove(); }; } </script> </body> </html>
事件委托的优点
1) 减小内存消耗使用事件委托可以大量节省内存,减少事件的定义,通过上面的示例可以看出,要为 ul 标签下的所有 li 标签添加点击事件,如果分别为每个 li 标签绑定事件,不仅写起来比较繁琐,而且对内存的消耗也非常大。而使用事件委托的方式将点击事件绑定到 ul 标签上,就可以实现监听所有 li 标签,简洁、高效。
2) 动态绑定事件在网页中,有时我们需要动态增加或移除页面中的元素,比如上面示例中动态的在 ul 标签中添加 li 标签,如果不使用事件委托,则需要手动为新增的元素绑定事件,同时为删除的元素解绑事件。而使用事件委托就没有这么麻烦了,无论是增加还是减少 ul 标签中的 li 标签,即不需要再为新增的元素绑定事件,也不需要为删除的元素解绑事件。
所以使用事件委托动态绑定事件可以减少很多重复工作的。
总结
要使用事件委托,需要保证事件能够发生冒泡,适合使用事件委托的事件有 click、mousedown、mouseup、keydown、keyup、keypress 等。需要注意的是,虽然 mouseover 和 mouseout 事件也会发生事件冒泡,但处理起来非常麻烦,所以不推荐在 mouseover 和 mouseout 事件中使用事件委托。
到此这篇关于JavaScript事件委托(事件代理)的文章就介绍到这了,更多相关js事件委托(事件代理)内容请搜索本网站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本网站!
您可能感兴趣的文章:
- js中的事件委托或是事件代理使用详解
- js事件委托和事件代理案例分享
- JS事件处理机制及事件代理(事件委托)实例详解
- JS 事件绑定、事件监听、事件委托详细介绍
- javascript事件委托的方式绑定详解
- JavaScript中的事件委托及好处
- JavaScript动态添加事件之事件委托