由于IE的JScript和DOM对象使用不同的垃圾收集方式,因此闭包在IE中会导致一些问题,就是内存泄漏的问题,也就是无法销毁驻留在内存中的元素。
当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。
例如:以下代码会存在内存泄露:
下面“btn.onclick”事件,没有被移除,一直存在内存中,没有被销毁
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function(){ document.getElementById("myDiv").innerHTML = "Processing..."; } </script>
应该改成以下写法:
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function(){ btn.onclick = null; document.getElementById("myDiv").innerHTML = "Processing..."; } </script>
或者采用事件委托(个人认为“document.onclick”,在字面意思上,没有上面“onclick ”的效率高。)
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> document.onclick = function(event){ event = event || window.event; if(event.target.id == "myBtn"){ document.getElementById("myDiv").innerHTML = "Processing..."; } } </script>
demo测试
多个重复的点击事件,只是为了看看能否更明显看到内存变化
值得疑惑的是:
在进行内存泄漏测试过程中,我一开始使用的 IE11 (window.navigator.platform="Win32") 浏览器下,看不出内存有上涨的趋势。
我换了一个设备的IE11(window.navigator.platform="Win64"),就可以看到内存涨了。
不知道这个IE的内存回收机制,是否和IE的版本有关。
以下是64位下的IE11测试数据,可以看到10多分钟过去,内存涨了30MB
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>内存泄漏测试</title> 5 </head> 6 <body> 7 <div id="myDiv"> 8 <input type="button" value="Click me" id="myBtn"> 9 </div> 10 <div id="myDiv2"> 11 <input type="button" value="Click me" id="myBtn2"> 12 </div> 13 14 <div id="myDiv3"> 15 <input type="button" value="Click me" id="myBtn3"> 16 </div> 17 <div id="myDiv4"> 18 <input type="button" value="Click me" id="myBtn4"> 19 </div> 20 21 </body> 22 <script> 23 var btn = document.getElementById("myBtn"); 24 btn.onclick = function(){ 25 document.getElementById("myDiv").innerHTML = "Processing..."; 26 } 27 28 var btn2 = document.getElementById("myBtn2"); 29 btn2.onclick = function(){ 30 document.getElementById("myDiv2").innerHTML = "Processing...2"; 31 } 32 33 var btn3 = document.getElementById("myBtn3"); 34 btn3.onclick = function(){ 35 document.getElementById("myDiv3").innerHTML = "Processing...3"; 36 } 37 38 var btn4 = document.getElementById("myBtn4"); 39 btn4.onclick = function(){ 40 document.getElementById("myDiv4").innerHTML = "Processing...4"; 41 } 42 </script> 43 </html>