如果我有一个谁拥有绑定到这些事件侦听器,做我需要删除这些事件侦听儿童的父元素之前,我清楚的家长吗? (即parent.innerHTML = '';
)如果事件侦听器没有从元素中解除绑定,那么是否可能会发生内存泄漏?在删除元素之前是否需要删除事件侦听器?
39
A
回答
24
简短的回答:是
龙答:大多数浏览器正确处理这一点,并删除这些处理程序本身。有一些旧的浏览器(IE 6和7,如果我记得正确),这是搞砸了。是的,可能会有内存泄漏。你不必担心这一点,但你需要。看看this document。
21
只是为了在这里更新的信息。我一直在测试各种浏览器,专门针对iframe onload事件上的循环依赖事件侦听器的内存泄漏。
使用(的jsfiddle内存测试干扰,所以用自己的服务器来测试这个)代码:
<div>
<label>
<input id="eventListenerCheckbox" type="checkbox" /> Clear event listener when removing iframe
</label>
<div>
<button id="startTestButton">Start Test</button>
</div>
</div>
<div>
<pre id="console"></pre>
</div>
<script>
(function() {
var consoleElement = document.getElementById('console');
window.log = function(text) {
consoleElement.innerHTML = consoleElement.innerHTML + '<br>' + text;
};
}());
(function() {
function attachEvent(element, eventName, callback) {
if (element.attachEvent)
{
element.attachEvent(eventName, callback);
}
else
{
element[eventName] = callback;
}
}
function detachEvent(element, eventName, callback) {
if (element.detachEvent)
{
element.detachEvent(eventName, callback);
}
else
{
element[eventName] = null;
}
}
var eventListenerCheckbox = document.getElementById('eventListenerCheckbox');
var startTestButton = document.getElementById('startTestButton');
var iframe;
var generatedOnLoadEvent;
function createOnLoadFunction(iframe) {
var obj = {
increment: 0,
hugeMemory: new Array(100000).join('0') + (new Date().getTime()),
circularReference: iframe
};
return function() {
// window.log('iframe onload called');
obj.increment += 1;
destroy();
};
}
function create() {
// window.log('create called');
iframe = document.createElement('iframe');
generatedOnLoadEvent = createOnLoadFunction(iframe);
attachEvent(iframe, 'onload', generatedOnLoadEvent);
document.body.appendChild(iframe);
}
function destroy() {
// window.log('destroy called');
if (eventListenerCheckbox.checked)
{
detachEvent(iframe, 'onload', generatedOnLoadEvent)
}
document.body.removeChild(iframe);
iframe = null;
generatedOnLoadEvent = null;
}
function startTest() {
var interval = setInterval(function() {
create();
}, 100);
setTimeout(function() {
clearInterval(interval);
window.log('test complete');
}, 10000);
}
attachEvent(startTestButton, 'onclick', startTest);
}());
</script>
如果没有内存泄漏,使用的内存会后,各地1000KB以下增加测试运行。但是,如果有内存泄漏,内存将增加约16,000kb。首先删除事件监听器总是会导致内存使用率降低(无泄漏)。
结果:
- IE6 - 内存泄漏
- IE7 - 存储器泄漏
- IE8 - 无存储器泄漏
- IE9 - 内存泄漏(???)
- IE10 - 内存泄漏(???)
- IE11 - 无内存泄漏
- 边缘(20) - 无内存泄漏
- 铬(50) - 没有内存泄漏
- 火狐(46) - 很难说,不漏得厉害,所以也许只是低效的垃圾收集器?完成一个额外的4MB没有明显的原因。
- 歌剧院(36) - 没有内存泄漏
- 野生动物园(9) - 没有内存泄漏
结论: 前沿的应用,也许可以与没有删除事件侦听器脱身。但我仍然认为这是一个很好的做法,尽管有这种烦恼。
相关问题
- 1. 删除元素是否也会删除其事件侦听器?
- 2. 在删除它们所连接的元素之前,是否需要删除javascript事件侦听器?
- 3. 的JavaScript:在元素中删除事件侦听器
- 4. 关闭模块之前删除事件侦听器
- 5. 我是否需要在2016年移除事件侦听器?
- 6. 如何从DOM元素中删除事件侦听器?
- 7. JQuery - 删除元素中的所有事件侦听器
- 8. 如何删除事件侦听器?
- 9. 如何删除事件侦听器?
- 10. Chrome删除事件侦听器?
- 11. gmap3删除事件侦听器
- 12. 的NodeJS删除事件侦听器
- 13. Hammer.js不能删除事件侦听器
- 14. 删除新库的事件侦听器
- 15. 删除重复的事件侦听器
- 16. 删除事件侦听器3
- 17. 删除Dojo dGrid的事件侦听器
- 18. 删除事件侦听器的当前发射事件
- 19. 在删除元素之前,我需要解除绑定jquery事件吗?
- 20. 当您使用.html()删除元素时,jQuery中的事件侦听器是否会自动删除?
- 21. DOM元素被删除之前是否有任何事件?
- 22. 删除匿名侦听器
- 23. 删除元素上事件侦听器的最佳方法是什么?
- 24. AS3不会删除事件侦听#1009
- 25. 删除事件监听器
- 26. 删除事件监听器
- 27. 删除事件监听器
- 28. 在自动创建的多个元素上删除事件侦听器
- 29. 在删除表之前,我们是否真的需要删除外键?
- 30. 删除文件之前需要fsync吗?
事实上:虽然目前大多数浏览器不会遭受它那么多,IE 7是仍然普遍使用。另请参阅[JavaScript中的内存泄漏模式](http://www.ibm.com/developerworks/web/library/wa-memleak/)。 – 2011-05-17 16:41:51
是否有人有足够的知识来更新目前的浏览器市场?或者这值得单独提问? IE7我认为[几乎停止](http://theie7countdown.com/),而[ie8](http://theie8countdown.com/)仍然悬而未决。 IE8处理放弃的事件侦听器吗? – 2014-07-10 20:41:59
6年后,我想'IE <10'可以安全地认为是过时和不使用任何人谁去在这一点上超过雅虎和AOL等网站。任何使用IE的人都可能成为印度手机诈骗的受害者,或者得到病毒,而不是因为事件处理程序的问题而使浏览器的螃蟹变慢。 – 2017-05-19 06:56:06