Search This Blog

Mind freaker Stuff

Please Visit my new blog http://www.mindfreakerstuff.com for new articles related to web and mobile designing.

Thursday, September 29, 2011

Alternatives to innerHTML

the focus of this article will be to show you ways of doing things commonly reserved for innerHTML with only DOM methods. In each example, the innerHTML method will be shown, followed by its DOM based alternative.

What's wrong with innerHTML?

A few things:
  • It's not a standard. It's a proprietary property that Microsoft introduced (along with the less popular outerHTML) that the other browser makers picked up.
  • Since it's not a standard, it isn't terribly future proof. It's not supposed to work under the application/xhtml+xml MIME type that XHTML documents are supposed to be served under. (Firefox 1.5 changed this by allowing it for some reason)
  • innerHTML is a string. The DOM is not a string, it's a hierarchal object structure. Shoving a string into an object is impure and similar to wrapping a spaghetti noodle around an orange and calling it lunch.
  • It makes for some nearly illegible code in a lot of instances, with escaped quotes and plus signs all over the place appending data to the string, which in my opinion makes it difficult to maintain.

Ok...anything good about it?

Sure. Don't get me wrong, I had a long and productive love affair with innerHTML, using it in everything from favelets to games.
  • It's faster than DOM methods. By a lot. [ http://www.quirksmode.org/dom/innerhtml.html ]
  • It's less verbose than DOM methods.
  • It allows you to take arbitrary chunks of markup and drop them into a document without having to parse them.
It was when my favelets stopped working for people when they were invoked on application/xhtml+xml sites that I decided to wash my hands of it (and do a lot of re-coding).

Example One

[1a] Creating an element.

This example introduces three DOM methods. The first is createElement, a method of the document object. It does exactly that - creates an element. It's argument is the name of the element you want created.
The second is the setAttribute method. This method is the equivalent of object.attributeName = "value";.
The last is the appendChild method. This method will append your newly created element to the element it is invoked on. The element will be the newest child of the parent element, and appear last in the element.
innerHTML

document.getElementById("mContainer").innerHTML = "<div id=\"myDiv\"></div>";
DOM

// create a DIV element, using the variable eDIV as a reference to it
eDIV = document.createElement("div");
//use the setAttribute method to assign it an id
eDIV.setAttribute("id","myDiv");
// append your newly created DIV element to an already existing element.
document.getElementById("mContainer").appendChild(eDIV);
	

[1b] Creating an Element with Text

In this example you'll use the createTextNode method of the document object. This method will -- you guessed it -- create a text node. It's important to note that a text node is just that: text. Any markup that you pass to createTextNode will be rendered as text, not as HTML.
innerHTML

document.getElementById("mContainer").innerHTML = "<div id=\"myDiv\">hello world</div>";
DOM

// create a DIV element, using the variable eDIV as a reference to it
eDIV = document.createElement("div");
//use the setAttribute method to assign it an id
eDIV.setAttribute("id","myDiv");
// add the text "hello world" to the div with createTextNode
eDIV.appendChild(document.createTextNode("hello world"));
// append your newly created DIV element to an already existing element.
document.getElementById("mContainer").appendChild(eDIV);
	

[1c] Creating an Element Containing Hyperlinked Text

In this example, you'll create two elements. The div element as you did before, in addition to an anchor element. You'll then append the text node ("hello world") to the anchor element rather than the div element since that's the text you want hyperlinked (the text node is a child of the anchor) and finally you'll append the anchor to the div.
innerHTML

document.getElementById("mContainer").innerHTML = "<div id=\"myDiv\"><a href=\"http://slayeroffice.com\">hello world</a></div>";
DOM

// create a DIV element, using the variable eDIV as a reference to it
eDIV = document.createElement("div");
//use the setAttribute method to assign it an id
eDIV.setAttribute("id","myDiv");
 // create your anchor element
eAnchor = document.createElement("a");
// set its href attribute with the setAttribute method
eAnchor.setAttribute("href","http://slayeroffice.com");
// add the text "hello world" to the anchor element
eAnchor.appendChild(document.createTextNode("hello world"));
 // append your newly created anchor element to the div
eDIV.appendChild(eAnchor);
// append your newly created DIV element to an already existing element.
document.getElementById("mContainer").appendChild(eDIV);
	

[1d] Creating an Element Containing Hyperlinked Text and an Event Handler

innerHTML

document.getElementById("mContainer").innerHTML = "<div id=\"myDiv\"><a href=\"http://slayeroffice.com\" onmouseover="doStuff();">hello world</a></div>";
DOM

// create a DIV element, using the variable eDIV as a reference to it
eDIV = document.createElement("div");
//use the setAttribute method to assign it an id
eDIV.setAttribute("id","myDiv");
 // create your anchor element
eAnchor = document.createElement("a");
// set its href attribute with the setAttribute method
eAnchor.setAttribute("href","http://slayeroffice.com");
// add our event handler to the anchors mouseover event
eAnchor.onmouseover = doStuff;
// add the text "hello world" to the anchor element
eAnchor.appendChild(document.createTextNode("hello world"));
 // append your newly created anchor element to the div
eDIV.appendChild(eAnchor);
// append your newly created DIV element to an already existing element.
document.getElementById("mContainer").appendChild(eDIV);
	

[1e] Creating an Element Containing Hyperlinked Text and an Event Handler that Takes an Argument

innerHTML

document.getElementById("mContainer").innerHTML = "<div id=\"myDiv\"><a href=\"http://slayeroffice.com\" onmouseover=\"doStuff('foo');\">hello world</a></div>";
DOM

// create a DIV element, using the variable eDIV as a reference to it
eDIV = document.createElement("div");
//use the setAttribute method to assign it an id
eDIV.setAttribute("id","myDiv");
 // create your anchor element
eAnchor = document.createElement("a");
// set its href attribute with the setAttribute method
eAnchor.setAttribute("href","http://slayeroffice.com");
// add our event handler to the anchors mouseover event
eAnchor.onmouseover = function() { doStuff("foo") };
// add the text "hello world" to the anchor element
eAnchor.appendChild(document.createTextNode("hello world"));
 // append your newly created anchor element to the div
eDIV.appendChild(eAnchor);
// append your newly created DIV element to an already existing element.
document.getElementById("mContainer").appendChild(eDIV);
	
Note: Simon Willison points out that the above example is a circular reference that will cause memory leaks in Internet Explorer. See this article by Mark Wubben for one solution, and be sure to unattach your event handlers when your document unloads

No comments:

Post a Comment