Javascript教程:关于内存泄漏问题(3)

http://www.itjxue.com  2015-08-06 23:21  来源:未知  点击次数: 

http://talideon.com/weblog/2005/03/js-memory-leaks.cfm 一文中的方法类似:

/*
* EventManager.js
* by Keith Gaughan
*
* This allows event handlers to be registered unobtrusively, and cleans
* them up on unload to prevent memory leaks.
*
* Copyright (c) Keith Gaughan, 2005.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* (CPL) which accompanies this distribution, and is available at
* http://www.opensource.org/licenses/cpl.php
*
* This software is covered by a modified version of the Common Public License
* (CPL), where Keith Gaughan is the Agreement Steward, and the licensing
* agreement is covered by the laws of the Republic of Ireland.
*/
//  For implementations that don't include the push() methods for arrays.
if(!Array.prototype.push){
    Array.prototype.push=function(elem){
         this[this.length]=elem;
    }
}
var  EventManager={
    _registry: null,
    Initialise: function(){
         if(this._registry==null){
             this._registry=[];
             //  Register the cleanup handler on page unload.
             EventManager.Add(window,"unload" ,this.CleanUp);
         }
    },
    /*
     * Registers an event and handler with the manager.
     *
     * @param  obj         Object handler will be attached to.
     * @param  type        Name of event handler responds to.
     * @param  fn          Handler function.
     * @param  useCapture  Use event capture. False by default.
     *                     If you don't understand this, ignore it.
     *
     * @return True if handler registered, else false.
     */
    Add: function(obj, type, fn, useCapture){
         this.Initialise();
         //  If a string was passed in, it's an id.
         if(typeof obj=="string"){
            obj = document.getElementById(obj);
         }
         if(obj==null || fn==null){
            return  false ;
         }
         // Mozilla/W3C listeners?
         if(obj.addEventListener){
            obj.addEventListener(type, fn, useCapture);
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: useCapture});
            return  true ;
         }
         //  IE-style listeners?
         if(obj.attachEvent && obj.attachEvent("on" + type,fn)){
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: false });
            return true ;
         }
         return false ;
    },
    /* *
     * Cleans up all the registered event handlers.
     */
    CleanUp: function(){
         for(var i=0;i<EventManager._registry.length;i++){
             with(EventManager._registry[i]) {
                 // Mozilla/W3C listeners?
                 if(obj.removeEventListener) {
                    obj.removeEventListener(type, fn, useCapture);
                 }
                 else if(obj.detachEvent){//  IE-style listeners?
                    obj.detachEvent("on"+type,fn);
                 }
             }
         }
         //  Kill off the registry itself to get rid of the last remaining
         //  references.
         EventManager._registry = null ;
    }
};

使用起来也很简单:

<html>
<head>
<script type=text/javascript src=EventManager.js></script>
<script type=text/javascript>   
function onLoad(){   
   EventManager.Add(document.getElementById(testCase),click,hit);
   return true;   
}   
function hit(evt) {       
   alert(click);   
}
</script>
</head>
<body onload='javascript: onLoad();'>
<div id='testCase' style='width:100%; height: 100%; background-color: yellow;'> 
<h1>Click me!</h1>
</div>
</body>
</html>

google map api同样提供了一个类似的函数用在页面的unload事件中,解决Closure带来的内存泄露问题。

当然,如果你不嫌麻烦,你也可以为每个和native object有关的就阿vascript object编写一个destoryMemory函数,用来手动调用,从而手动解除Dom对象的事件绑定。

还有一种就是不要那么OO,抛弃Dom的一些特性,用innerHTML代替appendChild,避开循环引用。详细见http://birdshome.cnblogs.com/archive/2005/02/16/104967.html中的讨论贴。

(责任编辑:IT教学网)

更多

推荐Javascript/Ajax文章