JavaScript性能优化之事件委托

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript性能优化之事件委托相关的知识,希望对你有一定的参考价值。

1 内存和性能

  在javascript中,添加到页面上的事件处理程序的数量直接关系到页面的整体运行性能

  首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差。

  其次,必须事先指定所有事件处理程序,会导致DOM访问次数增加,会延迟整个页面的交互就绪时间。

2 事件委托

  事件委托就是事件目标本身不处理事件,而是把处理任务委托给其父元素或祖先元素。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

  事件委托解决了"事件处理程序过多"的问题。

  假定现在有个ul无序列表(id为items),其中li(id为item+序号)代表每个项,当点击项时需弹窗显示项的基本信息。

<ul id="items">
	<li id="item1">无序列表1</li>
	<li id="item2">无序列表2</li>
	<li id="item3">无序列表3</li>
</ul>

  采用事件绑定li的方法(addHandler是跨浏览器的添加事件处理程序函数,具体实现见JavaScript事件章节):  

var item1 = document.getElementById(‘item1‘);
var item2 = document.getElementById(‘item2‘);
var item3 = document.getElementById(‘item3‘);

EventUtil.addHandler(item1, "click", function(){
	alert("I am item1!");
});

EventUtil.addHandler(item2, "click", function(){
	alert("I am item2!");
});

EventUtil.addHandler(item3, "click", function(){
	alert("I am item3!");
});

  使用事件委托,只需在DOM树种尽量最高的层次添加一个事件处理程序。

var items = document.getElementById(‘items‘);
EventUtil.addHandler(items, "click", function(event){
	var event = EventUtil.getEvent(event);
	var target = EventUtil.getTarget(event);

	alert("I am " + target.id);
});

  这里,通过事件委托只为ul元素添加了一个onclick的事件处理程序。由于所有li都是这个ul的子节点,而且它们的事件会冒泡,所以单击事件最终会被这个函数处理。

  对比普通的事件绑定代码和使用事件委托后的代码,会发现使用事件委托后消耗更小:只获取了一个DOM节点,只添加了一个事件处理程序,占用的内存更小。

  所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用委托的技术。

3 移除事件处理程序

  减少浏览器代码和支持页面交互的JavaScript代码之间的连接,通常有两种方法:

  1.使用事件委托技术,限制建立的连接数量;

  2.在不需要的时候,移除事件处理程序

  如果没有很好地移除事件处理程序,会导致"空事件处理程序",进而也会影响程序内存和性能,造成空事件处理程序的原因:

  1.从文档中移除了带有事件处理程序的元素(removeChild(),replaceChild());

  2.带有事件处理程序的元素被innerhtml删除了。解决办法在innerHTML操作前通过给事件赋值null移除事件处理程序

  3.页面卸载的时候(IE8-),如果在页面被卸载前没有清理干净事件处理程序,那么它们就会滞留在内存。解决办法通过onunload事件处理程序移除所有事件处理程序。

以上是关于JavaScript性能优化之事件委托的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript学习之事件委托

深入理解-事件委托

JavaScript性能优化4——循环添加事件实现

JavaScript性能优化4——循环添加事件实现

高性能JavaScriptの笔记-- DOM操作

js 事件委托代理