导致性能降低或内存泄漏的原因是多方面的:
mTj易塔云建站-模板下载,web开发资源,技术博客 □:每个函数都是对象。都会占用内存。
mTj易塔云建站-模板下载,web开发资源,技术博客 □:内存中的对象越多,性能就越差。
mTj易塔云建站-模板下载,web开发资源,技术博客目前了解的提升性能的方法有:
mTj易塔云建站-模板下载,web开发资源,技术博客mTj易塔云建站-模板下载,web开发资源,技术博客一、事件委托。mTj易塔云建站-模板下载,web开发资源,技术博客mTj易塔云建站-模板下载,web开发资源,技术博客对“事件处理程序过多”问题的解决方案就是
事件委托。事件委托利用了事件冒泡,只指定一个时间处理程序,就可以管理某一类型的所有事件。
mTj易塔云建站-模板下载,web开发资源,技术博客例如:click事件会一直冒泡到document层,也就是说,我们可以为这个页面指定一个onclick事件处理程序,而不必给每个单击的元素分别添加事件处理程序。以下为例:
<ul id="myLinks">mTj易塔云建站-模板下载,web开发资源,技术博客
<li id="to">三</li>mTj易塔云建站-模板下载,web开发资源,技术博客
<li id="do">个</li>mTj易塔云建站-模板下载,web开发资源,技术博客
<li id="click">li</li>mTj易塔云建站-模板下载,web开发资源,技术博客
</ul>
其中包含3个被单击后会执行操作的列表项。传统做法是:
var item1 = document.getElementById("to");mTj易塔云建站-模板下载,web开发资源,技术博客
var item2 = document.getElementById("do");mTj易塔云建站-模板下载,web开发资源,技术博客
var item3 = document.getElementById("this");mTj易塔云建站-模板下载,web开发资源,技术博客
EventUtil.addHandler(item1,"click",function(event){mTj易塔云建站-模板下载,web开发资源,技术博客
location.href = "http://www.abc.com";mTj易塔云建站-模板下载,web开发资源,技术博客
});mTj易塔云建站-模板下载,web开发资源,技术博客
EventUtil.addHandler(item2,"click",function(event){mTj易塔云建站-模板下载,web开发资源,技术博客
location.title = "change了一个title";mTj易塔云建站-模板下载,web开发资源,技术博客
});mTj易塔云建站-模板下载,web开发资源,技术博客
EventUtil.addHandler(item3,"click",function(event){mTj易塔云建站-模板下载,web开发资源,技术博客
alert("你好")mTj易塔云建站-模板下载,web开发资源,技术博客
});
如果在一个复杂Web应用中,对所有可单击的元素都采用这种方式,那么结果就会有数不清的代码用于添加事件处理程序。
mTj易塔云建站-模板下载,web开发资源,技术博客此时,使用“事件委托”可以解决这个问题。
mTj易塔云建站-模板下载,web开发资源,技术博客事件委托,只需要在DOM树种尽量最高的层次上添加一个事件处理程序,如下:
// 事件委托mTj易塔云建站-模板下载,web开发资源,技术博客
var list = document.getElementById("myLinks");mTj易塔云建站-模板下载,web开发资源,技术博客
EventUtil.addHandler(list,"click",function(event){mTj易塔云建站-模板下载,web开发资源,技术博客
event = EventUtil.getEvent(event);mTj易塔云建站-模板下载,web开发资源,技术博客
var target = EventUtil.getTarget(event);//取得事件的目标哦mTj易塔云建站-模板下载,web开发资源,技术博客
switch(target.id){mTj易塔云建站-模板下载,web开发资源,技术博客
case "to" :mTj易塔云建站-模板下载,web开发资源,技术博客
document.title = "change了一个title";mTj易塔云建站-模板下载,web开发资源,技术博客
break;mTj易塔云建站-模板下载,web开发资源,技术博客
case "do" :mTj易塔云建站-模板下载,web开发资源,技术博客
location.href = "http://www.abc.com";mTj易塔云建站-模板下载,web开发资源,技术博客
break;mTj易塔云建站-模板下载,web开发资源,技术博客
case "this" :mTj易塔云建站-模板下载,web开发资源,技术博客
alert("你好");mTj易塔云建站-模板下载,web开发资源,技术博客
break;mTj易塔云建站-模板下载,web开发资源,技术博客
};mTj易塔云建站-模板下载,web开发资源,技术博客
})
我们使用事件委托只给ul添加了一个onclick事件处理程序。
由于所有的列表子元素,它们的事件会冒泡不是吗?
mTj易塔云建站-模板下载,web开发资源,技术博客所以单击列表项的事件最终都会被这个函数处理。事件目标是被单击的列表项,所以通过检测id属性来决定是否采取适当的操作。注意:
mTj易塔云建站-模板下载,web开发资源,技术博客 □:与前面代码相比,这段代码的消耗更低,因为只取得了一个DOM,只添加了一个事件程序;
mTj易塔云建站-模板下载,web开发资源,技术博客 □:这种技术占用的内存更少。
mTj易塔云建站-模板下载,web开发资源,技术博客 □:如果可行的话,为document对象添加一个事件处理程序,用以处理页面上发生的各种特定类型的事件。优点:
mTj易塔云建站-模板下载,web开发资源,技术博客 △:document对象很快就可以访问,而且可以在页面生命周期的任何时点上为它添加事件处理程序(无需等待DOMContentLoaded或load事件)。只要可单击的元素呈现在页面上,就可以立即具备适当的功能;
mTj易塔云建站-模板下载,web开发资源,技术博客 △:在页面中设置时间处理程序所需的事件更少。只添加一个事件处理程序所需的DOM引用更少,说花的时间也更少;
mTj易塔云建站-模板下载,web开发资源,技术博客 △:整个页面占用的内存空间更少,能整体提升性能。
mTj易塔云建站-模板下载,web开发资源,技术博客最合适采用事件委托技术的事件:click、mousedown、mouseup、keydown、keyup、keypress。
mTj易塔云建站-模板下载,web开发资源,技术博客mTj易塔云建站-模板下载,web开发资源,技术博客二、移除事件处理程序。mTj易塔云建站-模板下载,web开发资源,技术博客mTj易塔云建站-模板下载,web开发资源,技术博客每当将事件处理程序指定给元素时,浏览器与JavaScript代码之间就会建立一个链接。
mTj易塔云建站-模板下载,web开发资源,技术博客链接越多,页面执行起来就越慢。所以,在不需要的时候移除事件处理程序,也能解决一部分性能问题。
mTj易塔云建站-模板下载,web开发资源,技术博客内存中留的那些过时的“空事件处理程序(dangling event handler)”,也是造成Web程序内存性能问题的主因。
mTj易塔云建站-模板下载,web开发资源,技术博客如果某个元素(带有事件处理程序)被innerHTML删除,那么已经添加到元素中的事件就无法被当做垃圾回收。下面:
<div id="myDiv">mTj易塔云建站-模板下载,web开发资源,技术博客
<input type="button" value="点击我吧" id="myBtn">mTj易塔云建站-模板下载,web开发资源,技术博客
</div>mTj易塔云建站-模板下载,web开发资源,技术博客
<script>mTj易塔云建站-模板下载,web开发资源,技术博客
var btn = document.getElementById("myBtn");mTj易塔云建站-模板下载,web开发资源,技术博客
btn.onclick = function(){mTj易塔云建站-模板下载,web开发资源,技术博客
//somethingmTj易塔云建站-模板下载,web开发资源,技术博客
document.getElementById("myDiv").innerHTML = "修改中。。。";mTj易塔云建站-模板下载,web开发资源,技术博客
}mTj易塔云建站-模板下载,web开发资源,技术博客
</script>
一个按钮,被包裹在div中,单击此按钮就讲按钮移除并替换成一条消息。
mTj易塔云建站-模板下载,web开发资源,技术博客但是问题是:
即使按钮移除了,它本身还带着一个事件处理程序。mTj易塔云建站-模板下载,web开发资源,技术博客所以那么最好的方式是手工断开引用:
var btn = document.getElementById("myBtn");mTj易塔云建站-模板下载,web开发资源,技术博客
btn.onclick = function(){mTj易塔云建站-模板下载,web开发资源,技术博客
//somethingmTj易塔云建站-模板下载,web开发资源,技术博客
btn.onclick = null;//表达了断开mTj易塔云建站-模板下载,web开发资源,技术博客
document.getElementById("myDiv").innerHTML = "修改中。。。";mTj易塔云建站-模板下载,web开发资源,技术博客
}
此时,我们先移除了按钮的事件处理程序。这样确保内存可以被再次利用,而从DOM中移除按钮也做到了干净利索。
mTj易塔云建站-模板下载,web开发资源,技术博客导致“空事件处理程序”的另一种情况,就是卸载页面的时候。
mTj易塔云建站-模板下载,web开发资源,技术博客IE8及早版本问题肯定是最多,但其他浏览器问题也不少。如果在页面被卸载前没有清理干净事件处理程序,那它们就会滞留在内存中。
mTj易塔云建站-模板下载,web开发资源,技术博客每次加载完页面再卸载页面时(可能是两个页面来回切换,也可能是点击了刷新按钮),内存中滞留的对象数目就会增加,因为事件处理程序占用的内存并没有被释放。
mTj易塔云建站-模板下载,web开发资源,技术博客一般来说,最好的方法就是在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。
mTj易塔云建站-模板下载,web开发资源,技术博客只要是通过onload事件处理程序添加的东西,最后都要通过onunload事件处理程序将它们移除。