|
|
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. If you were the coding God you think you are, your code would still be current.
So enough ego manipulation.
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 DOMgetHTML(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"));
As wrong as it is to view any part of a DOM as a text string this function will allow you to do just that.
Next we may need to clear the content of an element. Using innerHTML this would be as simple as assigning a blank string to an elements innerHTML. It’s not much more complicate with DOM:
Code: function clearContent(el) {
// first clone the object, without it’s child elements.
nEl = el.cloneNode(false);
// Pop the new element in before the old one.
el.parentNode.insertBefore(nEl,el);
// Now get rid of the one that has all that icky content
el.parentNode.removeChild(el);
}
clearContent(document.getElementById("myDiv"));
This function would be used when removing content from a page. It makes so much more sense to empty a node as opposed to assigning a blank string to it.
Sometimes we need to copy one node to another. This can be used for sorting, mirroring, or any other method that requires moving data around your document.
Code: function copyNode(source, dest) {
// Get source content
sEl = document.getElementById(source).cloneNode(true);
// remove your destination existing content
clearContent(document.getElementById(dest);
// add source content onto dest content
document.getElementById(dest).appendChild(sEl);
}
Notice this function makes use of the previous one. First we copy the data we want, then we remove the data we don’t want, then we copy the source data to the destination.
Now you are armed to work more effectively with the DOM structure. Embrace the standard. Don't use shortcuts they are evil. |
Comments :
spite 2006-09-06 #47
Hey, why not just use innerHTML
zzzeek 2006-09-07 #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-09 #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-09 #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-09 #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.
|