我正在构建一个带有requestAnimationFrame
循环的游戏,其中包含对jQuery html()
方法的调用。它只是在游戏操作旁边的状态窗口中更新文本。
我注意到Chrome的时间线监视器,DOM节点上升和上升,每分钟数千!当我改变我的代码时:
// creates a ton of DOM nodes
$("#readout").html(data);
到
// DOM nodes does not increase over time
document.getElementById('readout').innerHTML = data;
'内存泄漏'消失了。
答案 0 :(得分:7)
简短回答:不。
答案很长:您的页面/代码中可能还有其他内容。
内存泄漏通常是由Javascript引擎和DOM之间的循环引用引起的。例如:
var div = document.getElementById('divId');
div.onclick = function() {
doSomething(div);
};
脚本获取对页面上div的引用。到目前为止,我们没事。下一行将一个函数分配给DOM上的事件处理程序,创建从DOM到Javascript引擎的引用 - 泄漏的一半。函数体使用标签,它创建一个Closure--标签引用与函数一起保存,以便将来调用它。这样就完成了标签之间的循环引用 - >函数(DOM - > JS)和函数 - >标签(JS - > DOM),因此2将位于内存中,直到浏览器的进程被销毁。
因此,为了使您提到的任何一行代码泄露,必须消除上面附带事件的标记(或遵循类似模式的数据)。但是,jQuery的.html(字符串)不遗余力地阻止这些:
// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem, false ) );
elem.innerHTML = value;
}
所以它正在遍历所有标签内的标签,你正在运行.html(字符串)并在它们上运行cleanData(),这反过来就是这样:
jQuery.removeEvent( elem, type, data.handle );
从而防止泄漏。
因此,为了使用此方法泄漏内存而不浏览器内置.innerHTML,您必须触发一些非常模糊的浏览器错误(似乎不太可能),或更可能的东西否则你正在把它误认为jQuery的.html(字符串)。
答案 1 :(得分:2)
始终使用.empty().html(...)
而非.html()
.empty()
从您要删除的DOM对象中取消绑定事件侦听器,并正常删除它们。