Does removing a DOM element also remove your listening?

Asked

Viewed 97 times

6

I already know the appeal of Dirt collector.

My doubt is in relation to this recourse to the addEventListener.

Example

test.addEventListener('mouseover', function(){
  test.className = 'active';
});

test.addEventListener('mouseout', function(){
  test.className = '';
});

var i =0; setInterval(function(){
  count.innerHTML = ++i;
}, 1000);

setTimeout(function(){
  test.remove();
}, 5000);
#test{
  width:100px;
  height:50px;
  background : #0000FF;
}

#test.active{
  background : #00FF00;
}
<span id="count">0</span>

<div id="test">
</div>

Question

  • By doing the .remove() what happens to the bug? it gets a null reference?
  • Before simply removing the element I need to do removeEventListener? or GC will capture the bug?

1 answer

4


Removing from the DOM itself does not remove the event headphones. An example of this is that we can keep a reference to the element:

const inicio = new Date();
const test = document.getElementById('test');
test.addEventListener('click', function(segs) {
  const agora = new Date();

  console.log('clique! passados', Math.round((agora - inicio) / 1000), 'segundos');
});

test.remove();
console.log(test.parentElement);
test.click();
setTimeout(() => test.click(), 10000);
#test {
  width: 100px;
  height: 50px;
  background: #0000FF;
}

#test.active {
  background: #00FF00;
}
<span id="count">0</span>

<div id="test">
</div>

When a few years ago the SPA (single page Aplication) began to be popular and to stir a lot in the DOM without refresh of the page arose problems of memory leaks. Some of these leaks were because removing an element of the DOM does not release everything that was associated with the element.

It is also necessary to remove the event headphones by passing the same function to the method removeEventListener.

In your example that would be:

const test = document.getElementById('test');
const adicionarClasse = function() {
  this.className = 'active';
}
const removerClasse = function() {
  this.className = '';
}
test.addEventListener('mouseover', adicionarClasse);
test.addEventListener('mouseout', removerClasse);

setTimeout(function() {
  test.removeEventListener('mouseover', adicionarClasse);
  test.removeEventListener('mouseout', removerClasse);
  test.remove();
}, 5000);
#test {
  width: 100px;
  height: 50px;
  background: #0000FF;
}

#test.active {
  background: #00FF00;
}
<div id="test">
</div>

Related: an article in MDN on memory leakage (in English)

  • When you say "removing an element from the DOM does not release everything that was associated with the element", is it because there are still other active references to that element ? If there were none, it would all be caught by the GC no ?

  • @Isac yes, if there is nothing associated with the element or references within active scopes GC must remove the element by releasing the memory it had allocated.

  • @Sergio this goes against my previous research. If a DOM Element is Removed, are its listeners also Removed from memory?

  • In case you’re doing the click soon after the action could not be done because the GC has not captured the element?

  • @Guilhermelautert provided that references to the element GC does not remove. I’ve put together an example where I wait 10s for the click after I’ve removed the DOM element and it works.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.