Andrey
Andrey

Reputation: 21275

Removing an element from DOM

I use this method to escape strings of HTML code on client side:

function escapeHTML(str)
{
   var div = document.createElement('div');
   var text = document.createTextNode(str);
   div.appendChild(text);
   return div.innerHTML;
}; 

I am a bit concerned about memory leaks because I'm creating DOM element and not destroying it. The page is heavily Ajax'ed and will be refreshed very rarely, so there might be hundreds of calls to the method without page reload, which means those objects will be piling up, slowing down DOM traveral (e.g. with jQuery)

I tried to use document.removeChild(div), but IE gives an error "htmlfile: Invalid argument."

Any ideas?

Thanks, Andrey

Upvotes: 3

Views: 7738

Answers (4)

kangax
kangax

Reputation: 39168

You need to call removeChild on a an element itself:

function escapeHTML(str) {
   var div = document.createElement('div');
   var text = document.createTextNode(str);
   div.appendChild(text);
   var escapedHTML = div.innerHTML;
   div.removeChild(text);
   return escapedHTML;
}

One thing to remember is that this solution has quirks in some of the browsers (such as handling of newlines = "\n"). In Prototype.js, we explicitly check for some of these quirks and tweak the logic appropriately.

And of course it goes without saying that you should use feature detection, not browser sniffing ;)

You also don't really need to create new element every time function is called. Simply store it in a closure. For example:

var escapeHTML = (function(){

  var div = document.createElement('div');
  var text = document.createTextNode('');

  div.appendChild(text);

  return function(str) {
    text.data = str;
    return div.innerHTML;
  };
})();

If you employ this approach and keep element permanently, you might also consider cleaning it (i.e. nulling) on page unload, to prevent possible leaks.

Unfortunately, merely registering unload event handler prevents fast navigation (aka page cache) in many browsers. Most of the JS libraries already observe that event for cleanup purposes, so if you're using one (e.g. Prototype.js, jQuery, YUI), you shouldn't worry about it - page cache will be disabled anyway.

Otherwise, you might want to reconsider your options and either always create element at runtime, or employ different solution altogether (e.g. String.prototype.replace -based one):

function escapeHTML(str) {
  return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

Oh, and finally, you don't need to place ";" after function declarations; it is function expressions that are recommended to be ended with semicolons :)

Upvotes: 19

Anatoliy
Anatoliy

Reputation: 30073

DOM:

var node = document.getElementById('node_to_delete');
node.parentNode.removeChild(node);

jQuery:

$('#node_to_delete').remove();

Upvotes: 1

Mark
Mark

Reputation: 108512

If you have jQuery loaded, you could use the remove method.

Upvotes: 1

Wevah
Wevah

Reputation: 28242

IIRC you shouldn't have to care, since JS is garbage collected. If it's a huge deal, you could try parsing in chunks called via setTimeout() with a very short interval.

Upvotes: 0

Related Questions