谈JavaScript中的移除空事件处理程序

开发 前端
所谓空时间处理程序,就是在内存中留有的那些过时不用的事件处理程序。本文主要介绍JavaScript怎么移除空事件处理程序,希望对你有帮助,一起来看。

每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的JavaScript代码之间就会建立一个连接。这种链接越多,页面执行起来就越慢。所前所述,可以采用事件委托技术,限制建立的连接数量。另外,在不需要的时代移除事件处理程序,也是解决这个问题的一种方案。内存中留有那些过时不用的“空事件处理程序”,也是造成Web应用程序内存与性能问题的主要原因。

在两种情况下,可能会造成上述问题,第一种情况就是从文档 中移除带有事件处理程序的元素时,这可能是通过纯粹的DOM操作,例如使用removeChild()和replaceChild()方法,但更多地是发生在使用innerHTML替换页面中某一部分的时候。如果带有事件处理程序的元素被innerHTML删除了,那么原来添加到元素中的事件处理程序极有可能被当作垃圾回收。来看下面的例子:

  1. <div id="myDiv"> 
  2. <input type="button" value="Click Me" id="myBtn"> 
  3. </div> 
  4. <script type="text/javascript"> 
  5. var btn=document.getElementById("myBtn");  
  6. btn.onclick=function(){  
  7. document.getElementById("myDiv").innerHTML="Processing…";  
  8. }  
  9. </script> 

这里,有一个按钮被包含在<div>元素中,为避免双击,单击这个按钮时就将按钮移除并替换成一条消息;这是网站设计中非常流行的一种做法。但问题在于,当按钮被从页面中移除时,它还带着一个事件处理程序呢,在<div>元素中设置innerHTML可以把按钮移走,但事件处理各种仍然与按钮保持着引用联系。有的浏览器(尤其是IE)在这种情况下不会作出恰当的处理,它们很有可能会将对元素和事件处理程序的引用都保存在内存中。如果你想知道某个元即将被移除,那么最好手工移除事件处理程序。如下面的例子所示:

  1. <div id="myDiv"> 
  2. <input type="button" value="Click Me" id="myBtn"> 
  3. </div> 
  4. <script type="text/javascript"> 
  5. var btn=document.getElementById("myBtn");  
  6. btn.onclick=function(){  
  7. btn.onclick=null;  
  8. document.getElementById("myDiv").innerHTML="Processing…";  
  9. }  
  10. </script> 

 

在此,我们设置<div>的innerHTML属性之前,先移除了按钮的事件处理程序。这样就确保了内存可以被再次利用,而从DOM中移除按钮也做到了干净利索。

注:采用事件委托也有解决这个问题。如果事先知道将来有可能使用innerHTML替换掉页面中的某一部分,那么就可以不直接把事件处理程序添加到该部分的元素中,而通过把事件处理程序指定给最好层次的元素,同样能够处理该区域中的事件。

导致“空事件处理程序”的另一情况,就是卸载页面中的时候。毫不奇怪,IE在这种情况下依然是问题最多的浏览器,尽管其他浏览器或多或少也有类似的问题。如果在页面被卸载之前没有清理干净事件处理程序。那它们就会滞留在内存中。每次加载完页面再卸载页面时(可能是在两个页面间来加切换,也可以是单击了“刷新”按钮),内存中滞留的对象数目就会增加,因为事件处理程序占用的内存并没有被释放。

一般来说,最好的做法是在页面卸载之前 ,先通过onunload事件处理程序移除所有事件处理程序。在此,事件委托技术再次表现出它的优势——需要跟踪的事件程序越少,移除它们就越容易,对这种类似的操作,我们可把它想象成:只要是通过onload事件处理程序添加的东西,最后都要通过onunload事件处理程序将它们移除。

注:不要忘了,使用onunload事件处理程序意味着页面不会被缓存在bfcachek中,如果你在意这个问题,那么就只能在IE中通过onunload来移除事件处理程序了。

本文地址: http://www.yiiyaa.net/1361

【编辑推荐】

  1. JavaScript重构 模块划分和命名空间
  2. Javascript闭包(closure) 深入浅出
  3. 论Javascript的类继承
  4. 学习Javascript闭包(Closure)
  5. Javascript中闭包的作用域链
责任编辑:于铁 来源: yiiyaa.net
相关推荐

2011-06-16 14:38:18

JavaScript事件委托

2015-11-06 13:59:01

JavaScript事件处理

2010-09-16 09:37:21

JavaScript事

2009-06-17 09:48:11

javascript手事件参考

2009-08-12 18:28:09

C#事件处理程序

2017-03-14 13:51:23

AndroidView事件分发和处理

2017-08-28 15:21:29

异步处理回调函数异步编程

2021-11-11 11:24:54

JavaScript模型事件

2010-10-08 10:03:52

JavaScript图像

2021-09-02 10:24:54

JavaScript前端语言

2009-10-27 11:39:03

VB.NET事件处理程

2021-02-06 10:27:45

C#函数参数

2018-11-21 12:27:21

JavaScript 货币值区域

2020-08-19 08:29:22

JavaScript 对象函数

2013-09-13 13:15:28

AndroidWebViewJavaScript

2011-08-10 16:57:15

iPhone事件程序包

2020-09-25 11:10:51

运维故障排查监控

2021-10-28 17:05:11

IT运维故障

2014-06-27 09:34:03

AngularJS

2023-05-09 15:01:43

JavaScript编程语言异常处理
点赞
收藏

51CTO技术栈公众号