Magic DOM: Moving JavaScript forward

I have developed a 2 KB JavaScript library that does not depend on any external library. This library will improve your life in JavaScript for the better!

What does it do? Well, instead of doing this:

var dl = document.createElement('dl');
dl.className = 'my_dl';
var dt_equ = document.createElement('dt'); 
dt_equ.innerHTML = 'Equipments';
dt_equ.className = 'my_dt';
dl.appendChild(dt_equ);

You can do this with MagicDOM:

var dt_equ;
var dl = DL({'class': 'my_dl'},
    dt_equ = DT({'class': 'my_dt'}, 'Equipments'));

You could also write this:

SPAN({'class': 'babu'}, "Hello world")
->
<span class="babu">Hello world</span>

As you can see, the code gets more readable since it preserves the structure of HTML.

The syntax

Following DOM elements are supported:

  • UL, LI, TD, TR, TH,
  • TBODY, TABLE, INPUT, SPAN, B,
  • A, DIV, IMG, BUTTON,
  • H1, H2, H3, BR, TEXTAREA, FORM,
  • P, SELECT, OPTION, OPTGROUP, IFRAME, SCRIPT,
  • CENTER, DL, DT, DD, SMALL,
  • PRE, TN

These are all functions that have following signature:

DOMSHORTCUT({properties}?, ("String" | DOMSHORTCUT)*)

I.e. you can do following calls:

LI({style: 'color: red'}, 'I am fluffy')
->
<li style="color: red">I am fluffy</li>
DIV(UL(LI('Hello', ' ', 'nasty')))
->
<div><ul><li>Hello nasty</li></ul></div>

Get started?

Download MagicDOM.js:

Source it:

<script type="text/javascript" src="MagicDOM.js"></script>

You are ready to go :)

Related posts

Credits

MagicDOM is developed by me, but the initial idea is taken from MochiKit. MagicDOM can also be found in AJS [my own JavaScript library].

Announcements · Code · Code improvement · JavaScript 18. Jun 2007
8 comments so far

What about this kind of syntax:

var elem = createNode([
  'div', 
  {id:'foo', class:'someclass'}, [
    ['span', {class:'spanclass'}],
    'this is a text node ',
    ['br']
  ]
]
);

But the best thing would be if it supported good old innerHTML syntax.

I prefer the traditional syntax.
But it's a pretty good idea, congratulations! ;)

I have made a similar script -
http://www.openjs.com/scripts/...

Other implementations...
http://www.arantius.com/articl...
http://www.vivabit.com/code/do...

Interesting...

Just for the record, it will fail in IE for certain attributes...

e.g. "frameborder" on an iframe, "for" on a label

oh wait, Label isn't supported... nor fieldset or legend?

I would drop support for center and small too... since they are essentially deprecated now.

also for IE, appending a text node to a script tag won't work (bug in IE)

also, it should be noted (again for an IE bug), that the "type" attribute should be set right away (e.g. first) on an input tag... otherwise IE defaults to text, and you can't change it.

finally, (another IE bug), if you need to set the name attribute of a node (e.g. a form field), when you create it you have to do (and yeah, I know this is severely ugly).

document.createElement('<tagname name="desiredName">');

e.g.

document.createElement('<input name="specialExtra">');

I too created my own version of a generic DOM builder... and about 18 lines of it are purely to get around IE bugs. :P

Oh the fun of working with IE.

In IE javascript event handlers Ex. 'onsubmit':'parseFrom()' don't get translated properly in Magic DOM. Adding the following lines to createDOM will help handle some basic event handlers for elements.

else if(/^on(.*)/i.test(k))
eval("elm."+k+" = function(){"+attr+"};");

So createDOM looks like this now:

createDOM: function(name, attrs) {
        var i=0, attr;
        var elm = document.createElement(name);
		

        var first_attr = attrs[0];
        if(MagicDOM.isDict(attrs[i])) {
            for(k in first_attr) {
                attr = first_attr[k];
                if(k == "style")
                    elm.style.cssText = attr;
                else if(k == "class" || k == 'className')
                    elm.className = attr;
		else if(/^on(.*)/i.test(k))
			eval("elm."+k+" = function(){"+attr+"};");
		else {
                    elm.setAttribute(k, attr);
                }
            }
            i++;
        }

        if(first_attr == null)
            i = 1;

        for(var j=i; j < attrs.length; j++) {
            var attr = attrs[j];
            if(attr) {
                var type = typeof(attr);
                if(type == 'string' || type == 'number')
                    attr = TN(attr);
                elm.appendChild(attr);
            }
        }

        return elm;
    },

Interesting realization.
It would good to finish off it for correct work in MSIE.

It’s very good article. Great site with very good look and perfect information. I like it too.

It’s very good article. Great site with very good look and perfect information. I like it too.

Post a comment
Commenting on this post has expired.
© 2000-2009 amix. Powered by Skeletonz.