Break your innerHTML addiction

Javascript Best Practices

Many of us have been using the crutch of innerHTML to accomplish some great tasks with javascript. Now see how to do the same things correctly. Check out our full listing of innerHtml replacement functions.


Date : 2006-08-31


Updated April 11 2009 to correct issues with DOMgetHTML. Now there is both a DOMgetTEXT and a DOMgetHTML function.

I know, innerHTML came out first, it’s so easy to use. Browsers that use it render it faster than the pure DOM method. There are many reasons to use innerHTML, but one major reason not to:

It’s counter standard. The DOM standard does not include innerHTML and it probably never will. Viewing DOM elements as a text string is like viewing DNA as morse code. If we could all get behind the standards and use them it could force the software engineers (pronounced “Microsoft”) to actually care about the standards.

Of course it is not fair to tell you to stop using innerHTML without giving you a replacement. There is in fact a method for using DOM to accomplish everything that you have been using innerHTML to do.

Using DOM methods will benefit you in the long run as one day innerHTML will be on the dreaded "DEPRECATED" list (I called this back in 2006, and it now seems to be a reality). If you were the coding God you think you are, your code would still be current.

So enough ego manipulation. Lets see how to replace the innerHtml call with pure DOM calls.

There are basically 4 things that we use innerHTML for:


    1 – Adding HTML, or Creating Elements.
    2 – Getting the text within an Element
    3 – Removing content from an Element
    4 – Copying Content from one Element to another


So lets look at DOM methods for accomplishing these 4 points and see how to do them with clean pure DOM methods. Many of these methods you will have used before for other purposes but seeing how to use them to replace innerHTML functions will prove beneficial.

First then we will talk about adding HTML into your document. This can be used in AJAX and other Web2.0 settings to add content onto existing content. Here is how it can be done with purely DOM methods. This is a little more complicated than with innerHTML. We have to use a little different code for adding text only as opposed to adding HTML. But then the DOM is an object not a string, so lets deal with it as such.

First then lets add text:
Code:
function addText(el,strText, newID) {
  // create a DIV, called eDiv as Element Div
  eDIV = document.createElement("div");
  //assign an ID to the element because you may need to access it again
  eDIV.setAttribute("id", newID);
  // add a text node to the element.
  eDIV.appendChild(document.createTextNode(strText));
  // Now that we have created everything let’s add it to our DOM
  document.getElementById(el).appendChild(eDIV);
}

In this function el is a string carrying the ID of the element you want to add text to the end of. strText is the text node you want to add and newID is the ID of the newly added text, which will be placed inside a DIV element with the given ID.

This can be used for any kind of progressive loading of data where we continue to add new data onto the existing data. You can also use the existing code to figure out how to add other Elements to your DOM.

Now let’s move onto our second purpose. Getting the text within an element. We use this many times when using content in one element to create or determine content for another element. The first step is always going to be to get the content from the first element.

The following is a recursive function that will gather all nodes in a given element
Code:
function DOMgetTEXT(el) {
// No problem if it’s a text node
    if (el.nodeType == 3) return el.nodeValue;
    var txt = new Array(),i=0;
// If there is more to it, then let’s gather it all.
   while(el.childNodes[i]) {
     txt[txt.length] = DOMgetHTML(el.childNodes[i]);
     i++;
   }
   // return the array as a string
   return txt.join("");
}
// gather all the content of an Element as a string.
mText = DOMgetHTML(document.getElementById("myDIV"));


The above function will gather all the text nodes from a section of the DOM.

Page getting too long, the rest of the functions are on the next page...
http://www.bestcodingpractices.com/innerhtml_replacement_continued-15510.html

Comments :

spite 2006-09-06 #47

Hey, why not just use innerHTML

zzzeek 2006-09-06 #48

if innerHTML were ever removed from the API, within 2 hours someone will post an innerHTML library that takes an arbitrary text string, parses it for valid HTML, and applies the resulting elements as new DOM elements to the target node. thats all innerHTML really does. so whether or not the "innerHTML" attribute is part of the standard or not, the technique itself is orthogonal to DOM "correctness", and its a lot less tedious and error-prone than manipulating hundreds of nodes directly.

sammy01 2006-09-08 #51

Well, to answer the first poster, innerHTML adds terrible markup to xml/other code that is found in a div (for example), and renders it a useless function for when you're trying to do this. Not only that, but it behaves differently in IE than Firefox. In most apps, this isn't a problem, but as I found out today after over a year of successful innerHTML usage, it can cause some terrible problems.

DOMgetHTML doesn't do the job either, and it's name is a bad misnomer! innerHTML at least reads HTML, while DOMgetHTML actually just reads the text within tags. It should be renamed DOMgetText, really!

An example of what neither innerHTML, nor DOMgetHTML can do, and which I would love to know a DOM-based solution that can do it:

<div id="text"><value part="test"><![CDATA[<test text]]>test text2</value></div>

alert(document.getElementById('text'.innerHTML);
--> gives in IE : <value part="test">test text2</value>
--> gives in Firefox : <value part="test"><!--[CDATA[<test text]]-->test text2</value
(note the nasty markup, adding a "--" just before the CDATA, plus the difference between major browsers)
alert(DOMgetHTML(document.getElementById('text'))
--> gives test text2
No HTML at all!!

Does anyone have a REAL DOMgetHTML function lying around??

P.S the DOMgetHTML function has a bug in it.
line 3:if (el.nodeType == 3) return obj.nodeValue;
should be: if (el.nodeType == 3) return el.nodeValue;

sammy01 2006-09-08 #52

Sorry, here's the code again without the happy faces:

Code:
<div id="text"><value part="test"><![CDATA[test text]]>test text2</value></div>

alert(document.getElementById('text'.innerHTML);
--> gives in IE : <value part="test">test text2</value>
--> gives in Firefox : <value part="test"><!--[CDATA[test text]]-->test text2</value
(note the nasty markup, adding a "--" just before the CDATA, plus the difference between major browsers)
alert(DOMgetHTML(document.getElementById('text'))
--> gives test text2

BeachBum 2006-09-08 #53

Thanks for the Bug Fix Sammy, I Edited the function so it's correct now.
I see what you mean about the DOMgetHTML function... it should really be called DOMgetTXT... it doesn't show the HTML tags. Let me see what I can come up with.

BeachBum 2009-04-12 #413

Hey, I finally got the real DOMgetHTML function up. I know I promised that a long time ago but you know how it is.

  • Search For Articles