Asked  7 Months ago    Answers:  5   Viewed   34 times

If a DOM Element is removed, are its listeners removed from memory too?

 Answers

33

Modern browsers

Plain JavaScript

If a DOM element which is removed is reference-free (no references pointing to it) then yes - the element itself is picked up by the garbage collector as well as any event handlers/listeners associated with it.

var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null; 
// A reference to 'b' no longer exists 
// Therefore the element and any event listeners attached to it are removed.

However; if there are references that still point to said element, the element and its event listeners are retained in memory.

var a = document.createElement('div');
var b = document.createElement('p'); 
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b); 
// A reference to 'b' still exists 
// Therefore the element and any associated event listeners are still retained.

jQuery

It would be fair to assume that the relevant methods in jQuery (such as remove()) would function in the exact same way (considering remove() was written using removeChild() for example).

However, this isn't true; the jQuery library actually has an internal method (which is undocumented and in theory could be changed at any time) called cleanData() (here is what this method looks like) which automatically cleans up all the data/events associated with an element upon removal from the DOM (be this via. remove(), empty(), html("") etc).


Older browsers

Older browsers - specifically older versions of IE - are known to have memory leak issues due to event listeners keeping hold of references to the elements they were attached to.

If you want a more in-depth explanation of the causes, patterns and solutions used to fix legacy IE version memory leaks, I fully recommend you read this MSDN article on Understanding and Solving Internet Explorer Leak Patterns.

A few more articles relevant to this:

  • JScript memory leaks
  • Memory leaks in IE8
  • JavaScript Memory Leaks

Manually removing the listeners yourself would probably be a good habit to get into in this case (only if the memory is that vital to your application and you are actually targeting such browsers).

Tuesday, June 1, 2021
 
mattltm
answered 7 Months ago
81

Update: Time marches on and so have our browsers. This technique is no longer recommended and you should use Dan's solution if you do not need to support version of Internet Explorer before 7.

Original solution (now outdated):

This will check if the element is entirely visible in the current viewport:

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}

You could modify this simply to determine if any part of the element is visible in the viewport:

function elementInViewport2(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top < (window.pageYOffset + window.innerHeight) &&
    left < (window.pageXOffset + window.innerWidth) &&
    (top + height) > window.pageYOffset &&
    (left + width) > window.pageXOffset
  );
}
Tuesday, June 1, 2021
 
jab
answered 7 Months ago
jab
25

second the valgrind... and I'll add electric fence.

Tuesday, July 27, 2021
 
edsk
answered 5 Months ago
17

I'm not sure why firefox isn't happy w/ this but I can say from experience that in IE6/7/8 you must set innerHTML = ""; on the object you want removed from the DOM. (if you created this DOM element dynamically that is)

$("#content tbody").empty(); might not be releasing these dynamically generated DOM elements.

Instead try something like the below (this is a jQuery plugin I wrote to solve the issue).

jQuery.fn.removefromdom = function(s) {
    if (!this) return;

    var bin = $("#IELeakGarbageBin");

    if (!bin.get(0)) {
        bin = $("<div id='IELeakGarbageBin'></div>");
        $("body").append(bin);
    }

    $(this).children().each(
            function() {
                bin.append(this);
                document.getElementById("IELeakGarbageBin").innerHTML = "";
            }
    );

    this.remove();

    bin.append(this);
    document.getElementById("IELeakGarbageBin").innerHTML = "";
};

You would call this like so: $("#content").removefromdom();

The only issue here is that you need to re-create your table each time you want to build it.

Also, if this does solve your issue in IE you can read more about this in a blog post that I wrote earlier this year when I came across the same problem.

Edit I updated the plugin above to be 95% JavaScript free now so it's using more jQuery than the previous version. You will still notice that I have to use innerHTML because the jQuery function html(""); doesn't act the same for IE6/7/8

Wednesday, August 4, 2021
 
mschuett
answered 4 Months ago
75

There's a HTML5 API called MutationObserver and it has pretty good support

Here's an example:

// Element is the whatever subtree/element you need to watch over
var in_dom = document.body.contains(element);
var observer = new MutationObserver(function(mutations) {
    if (document.body.contains(element)) {
        if (!in_dom) {
            console.log("element inserted");
        }
        in_dom = true;
    } else if (in_dom) {
        in_dom = false;
        console.log("element removed");
    }

});
observer.observe(document.body, {childList: true, subtree: true});
Saturday, August 14, 2021
 
waylaidwanderer
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share