我一直在构建一个大型单页面应用程序,最近开始探索JS中的内存泄漏。而且我认为我的内存泄漏是因为 - 当我在Chrome中使用Profiles(快照)功能时 - 我发现我有很多独立的DOM元素。
以下是我的设置的简化视图:
<div id="container">
<div class="buttons">
<a class=".btn" href="/someurl/"> Button A</a>
<a class=".btn" href="/someurl/"> Button B</a>
<a class=".btn" href="/someurl/"> Button C</a>
</div>
<div class="ajaxHolder"></div>
</div>
因此,如果用户点击按钮A,我会使用AJAX调用将内容加载到.ajaxHolder
。像这样:
//This is the content...
<div class="contentA">
<p>some text...</p>
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
</div>
我的 MAIN脚本文件中也有两个功能。一个是这样的:
//Click event bound to a.btn which tigger the ajax call
$(.buttons).on('click', '.btn', function(){
//Do ajax here...
//on success...
var holder = $(".ajaxHolder");
holder.children().off().remove(); // Is this the way to do this??
holder.off().empty(); //I don't think I need .off() here, but I guess it can't hurt...
holder.append(ajaxSuccessData);
});
到目前为止一切顺利。但是现在加载了内容,我在 MAIN脚本文件中也有这个功能:
//So here, I am binding an event to the checkboxes...
$(".ajaxHolder").on('change', '.checkbox', function(){
//Do something...
});
所以现在如果用户按下按钮B,例如,.ajaxHolder
被清空,但所有那些与我的复选框相关的事件似乎都停留在那里,因为它们出现在我的分离的DOM树中。
我在这里缺少什么?如何确保我在这样运行的单个页面应用程序中没有任何分离的DOM元素?
奖金问题:我有很多事件都是这样的:
$(".ajaxHolder").on('someEvent...','.someClass....', someFunction());
也就是说,一切都始终附加到我的.ajaxHolder
,因为我必须使用事件委托,因为.ajaxHolder
将永远存在 - 而其他加载的项目并不总是存在,所以我不能简单地做$(button).on('click')...
等等。
这也是正确的方法吗?我可以附加多少内容.ajaxHolder
或者这样做是否有问题?
编辑:这是我的控制台的图像,如果这有帮助的话。
答案 0 :(得分:1)
不确定这是否仍然相关,但是从我收集的控制台图像中你使用的是bootstrap工具提示,它们似乎持有对DOM节点的引用。我建议你通过API
调用destroy方法答案 1 :(得分:-1)
答案 2 :(得分:-3)
执行此操作的最佳方法是使用$(selector).off()取消绑定所有事件侦听器。方法,然后使用$(selector).remove();删除元素。
由于事件处理程序,它将停止发生的所有内存泄漏。