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中的讨论贴。
出处:蓝色理想
责任编辑:bluehearts
上一页 关于Javascript的内存泄漏问题 [2] 下一页 关于Javascript的内存泄漏问题 [4]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|