Site Moved

This site has been moved to a new location - Bin-Blog. All new post will appear at the new location.

Bin-Blog

Creating DOM in a much easier way

Everyone who have tried their hand at creating a DOM structure using the W3C method knows that it is not easy. It is a piece of cake using innerHTML. But when we try it using W3C methods like document.createElement, we will find that it takes ten times more time. So I have created a small function(50 lines) to do this in a much easier way.

See Demo

WARNING : Do not use this script. I have found some serious problems with this script. I will let you know when the problem is cleared. If you have any idea about how it can be solved, I am all ears.

UPDATE : This problem has been fixed - see $C() DOM Creator

innerHTML

Disadvantages

  • It is not standard. It's a property that IE introduced that the other browsers also used.
  • innerHTML is just a string. DOM is not a string, it's a hierarchal structure. The two are not supposed to mix.
  • One has to escape all the '"' characters in the string - after all the escaping the string becomes rather ugly - and long. Add a lot of plus(+) signs(for string concatenation) to this and we get a unmaintainable mess.

Advantages

  • Much simpler and easier than the W3C DOM Model.
  • Can be used to great effect with AHAH - this can't be done using the W3C model.
  • Faster than the W3C DOM Model

I will never say that you should not use innerHTML(even PPK says that using innerHTML is OK). But if you want to avoid using it, this script will make it easier.

Code


function $c(dom,id) {
 if(!id) var id = "";//The ID argument is optional
 //All necessary HTML tags - make sure not to include any tags that is also a valid attribute name - eg 'cite'
 var valid_tags = ",p,div,span,strong,em,u,img,pre,code,br,hr,a,script,link,table,tr,td,h1,h2,h3,h4,h5,h6,sup,sub,"+
  "ul,ol,li,dd,dl,dt,form,input,textarea,legend,label,fieldset,select,option,blockquote,";//Begining and ending commas are intentional - don't remove them
 var html = new Array();
 for(var tag in dom) {
  var child = false;
  var attributes = dom[tag];

  var ele = document.createElement(tag);
  //If the given attribute is a string, it is a text node
  if(typeof attributes == "string") child = document.createTextNode(attributes);
  else {//If it an array...
   for(var att in attributes) {
    var value = attributes[att];
    if(valid_tags.indexOf(","+att+",") != -1) { //If the attribute is a valid tag,
     //Find the dom sturcture of that tag.
     var node = new Object;
     node[att] = value;
     ele.appendChild($c(node,""));// :RECURSION:
    }
    else if(att == "text") child = document.createTextNode(value);//The text in the tag
    else ele.setAttribute(att,value);
   }
  }

  if(child && attributes) ele.appendChild(child);//Append the child if it exists
  html.push(ele);
 }

 if(!id) {//If no node is given, return the created node.(Exits the function)
  //for(var x in html) alert(x + " = " + html[x]);
  if(html.length == 1) return html[0];
  return html;
 }
 //If a node/id was given, append the created elements to that element.
 var node = id;
 if(typeof id == "string") node = document.getElementById(id);//If the given argument is an id.
 for(var i=0;el=html[i],i<html.length;i++) node.appendChild(el);
}

Samples

HTML Code


<div class="newly-added">
<code>This is a code</code>
<br />
<a href="http://www.bin-co.com/">This is a link</a>
<hr />
<span class="finally">Thats all folks.</span>
</div>

InnerHTML Code


var html = '<div class="newly-added"><code>This is a code</code><br />
<a href="http://www.bin-co.com/">This is a link</a><hr /><span class="finally">Thats all folks.</span></div>';
document.getElementById("insert-here").innerHTML = html;

W3C DOM Code


var ele = document.createElement("div");
ele.setAttribute('class',"newly-added");

//The Code tag
var ele_code = document.createElement("code");
var txt = document.createTextNode("This is a code");
ele_code.appendChild(txt);
ele.appendChild(ele_code);

var ele_br1 = document.createElement("br");
ele.appendChild(ele_br1);

//Create the anchor
var ele_a = document.createElement("a");
ele_a.setAttribute("href","http://www.bin-co.com/");
txt = document.createTextNode("This is a link");
ele_a.appendChild(txt);
ele.appendChild(ele_a);

var ele_hr = document.createElement("hr");
ele.appendChild(ele_hr);

var ele_span = document.createElement("span");
ele_span.setAttribute("class","finally");
txt = document.createTextNode("Thats all folks.");
ele_span.appendChild(txt);
ele.appendChild(ele_span);

document.getElementById("insert-here").appendChild(ele);

And Finally - $C Code


$C({
 div:{
  'class':'newly-added',//Class must be quoted - its a keyword
  code:'This is a code',
  br:'',
  a:{
   href:'http://www.bin-co.com/',
   text:'This is a link'
  },
  hr:'',
  span:{
   'class':'finally',
   text:'Thats all folks.'
  }
 }
},"insert-here");

Problems

This is a new script - so I have not much problems with it. But I found one - and it is a biggie. You can't use the same tag twice inside an element. I am using a associative array, so the index will be overwritten. I will try to solve this problem as soon as possible. This is very troubling if you want to create a list.

References

$C equivalents

1 Comment:

Thomas Woodard said...

Hi, cool. I was looking for someone else who had addressed this problem. I took a different approach, with a XMLHTTPResponse to DOM translator: http://domaxh.sourceforge.net