旧IE(7、8)DOM内存泄漏解决方案是否正确?
旧IE7/8 DOM内存泄漏问题分析与解决方案验证
首先得先搞懂原代码为啥会在IE7/8里造成内存泄漏——这俩旧版本的IE对DOM元素和JS对象之间的循环引用处理有bug。
原代码的泄漏根源:
- 我们用
var btn = document.getElementById("myBtn")拿到了按钮的JS对象引用 - 给
btn.onclick绑定了一个匿名函数,这个函数里又引用了父元素myDiv的DOM节点 - 而DOM结构上
myDiv是btn的父元素,相当于myDiv的DOM节点也间接引用了btn的DOM节点,进而关联到对应的JS对象
这就形成了一个循环引用链:JS对象(btn) → 事件函数 → DOM节点(myDiv) → DOM节点(btn) → JS对象(btn)。旧IE的垃圾回收器没法识别这种跨DOM和JS环境的循环引用,导致这部分内存永远不会被释放,每次点击都会泄漏一点内存。
再看你提到的解决方案:
你给出的内容只显示了HTML部分,没贴完整的JS逻辑,但如果你的解决方案是在替换myDiv的innerHTML之前,手动切断循环引用——也就是先把按钮的事件绑定清空,那这个方案完全能解决问题。比如正确的完整代码应该是这样:
<div id="myDiv"> <button id="myBtn">Click Me</button> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function(){ // 关键一步:解除按钮的事件绑定,切断循环引用链 btn.onclick = null; document.getElementById("myDiv").innerHTML = "Processing..."; }; </script>
为啥这能解决?因为我们在销毁btn这个DOM节点(通过替换父元素innerHTML)之前,先把JS对象(btn)和事件函数之间的关联切断了,同时也切断了事件函数对myDiv的引用,整个循环链就被打破了,旧IE的垃圾回收器就能正常回收这部分内存了。
反过来,如果你的解决方案只是重复了原HTML结构,JS逻辑和原来一模一样,那肯定没法处理内存泄漏问题——循环引用的根源没解决,泄漏还是会发生。
内容的提问来源于stack exchange,提问作者Kuan
相关产品推荐
相关产品推荐

