Javascript 在删除元素之前是否需要删除事件侦听器?
如果父元素的子元素绑定了事件侦听器,那么在清除父元素之前是否需要删除这些事件侦听器?(即,Javascript 在删除元素之前是否需要删除事件侦听器?,javascript,dom,memory-leaks,dom-events,Javascript,Dom,Memory Leaks,Dom Events,如果父元素的子元素绑定了事件侦听器,那么在清除父元素之前是否需要删除这些事件侦听器?(即,parent.innerHTML='';)如果从DOM中删除某个元素,而该元素未解除事件侦听器的绑定,是否会发生内存泄漏?简短回答:yes 详细回答:大多数浏览器都正确地处理了这个问题,并且自己删除了这些处理程序。有一些较旧的浏览器(如果我没记错的话,就是6和7)把这一切都搞砸了。是的,可能有内存泄漏。你不必为此担心,但你需要。看看。简短回答:是 详细回答:大多数浏览器都正确地处理了这个问题,并且自己删除了
parent.innerHTML='';
)如果从DOM中删除某个元素,而该元素未解除事件侦听器的绑定,是否会发生内存泄漏?简短回答:yes
详细回答:大多数浏览器都正确地处理了这个问题,并且自己删除了这些处理程序。有一些较旧的浏览器(如果我没记错的话,就是6和7)把这一切都搞砸了。是的,可能有内存泄漏。你不必为此担心,但你需要。看看。简短回答:是
详细回答:大多数浏览器都正确地处理了这个问题,并且自己删除了这些处理程序。有一些较旧的浏览器(如果我没记错的话,就是6和7)把这一切都搞砸了。是的,可能有内存泄漏。你不必为此担心,但你需要。请查看。仅更新此处的信息。我一直在测试各种浏览器,特别是iframe onload事件上循环相关事件侦听器的内存泄漏 使用的代码(JSFIDLE会干扰内存测试,因此请使用您自己的服务器来测试):
删除iframe时清除事件侦听器
启动测试
(功能(){
var consoleElement=document.getElementById('console');
window.log=函数(文本){
consoleElement.innerHTML=consoleElement.innerHTML+'
'+文本;
};
}());
(功能(){
函数attachEvent(元素、事件名、回调){
if(元素附件)
{
元素attachEvent(eventName,回调);
}
其他的
{
元素[eventName]=回调;
}
}
函数detachEvent(元素、事件名、回调){
if(element.detachEvent)
{
detachEvent(eventName,回调);
}
其他的
{
元素[eventName]=null;
}
}
var eventListenerCheckbox=document.getElementById('eventListenerCheckbox');
var startTestButton=document.getElementById('startTestButton');
var-iframe;
风险值生成的非风险事件;
函数createOnLoadFunction(iframe){
var obj={
增量:0,
hugeMemory:新数组(100000).join('0')+(new Date().getTime()),
循环引用:iframe
};
返回函数(){
//log('iframe onload called');
对象增量+=1;
破坏();
};
}
函数create(){
//log('create called');
iframe=document.createElement('iframe');
generatedOnLoadEvent=createOnLoadFunction(iframe);
attachEvent(如果框架为“onload”,生成OnLoadEvent);
document.body.appendChild(iframe);
}
函数销毁(){
//log('destroy called');
如果(eventListenerCheckbox.checked)
{
detachEvent(iframe,“onload”,generatedOnLoadEvent)
}
document.body.removeChild(iframe);
iframe=null;
generatedOnLoadEvent=null;
}
函数startTest(){
var interval=setInterval(函数(){
创建();
}, 100);
setTimeout(函数(){
间隔时间;
window.log(“测试完成”);
}, 10000);
}
附件(开始按钮,'onclick',开始按钮);
}());
如果没有内存泄漏,则在运行测试后,使用的内存将增加约1000kb或更少。但是,如果内存泄漏,内存将增加约16000KB。首先删除事件侦听器通常会降低内存使用率(无泄漏)
结果:
- IE6-内存泄漏
- IE7-内存泄漏
- IE8-无内存泄漏
- IE9-内存泄漏(???)
- IE10-内存泄漏(???)
- IE11-无内存泄漏
- 边缘(20)-无内存泄漏
- Chrome(50)-无内存泄漏
- Firefox(46)-很难说,不会严重泄漏,所以可能只是低效的垃圾收集器?在没有明显原因的情况下,使用额外4MB完成
- Opera(36)-无内存泄漏
- Safari(9)-无内存泄漏
前沿应用程序可能不需要删除事件侦听器。但我还是认为这是一个好的做法,尽管恼火。 < P>只是在这里更新信息。我一直在测试各种浏览器,特别是iframe onload事件上循环相关事件侦听器的内存泄漏 使用的代码(JSFIDLE会干扰内存测试,因此请使用您自己的服务器来测试):
删除iframe时清除事件侦听器
启动测试
(功能(){
var consoleElement=document.getElementById('console');
window.log=函数(文本){
consoleElement.innerHTML=consoleElement.innerHTML+'
'+文本;
};
}());
(功能(){
函数attachEvent(元素、事件名、回调){
if(元素附件)
{
元素attachEvent(eventName,回调);
}
其他的
{
元素[eventName]=回调;
}
}
函数detachEvent(元素、事件名、回调){
if(element.detachEvent)
{
detachEvent(eventName,回调);
}
其他的
{
元素[eventName]=null;
<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>