如果我有一個誰擁有綁定到這些事件偵聽器,做我需要刪除這些事件偵聽兒童的父元素之前,我清楚的家長嗎? (即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