Painless DOM building with mkup +

Creating DOM nodes from Javascript can be painful. The amount of code needed to create nodes and to reference each other as needed is non-acceptable, and the resulting code is far away from being readable or maintainable.
There are some projects out there that try to solve this issue, but their API feels alien inside a Javascript environment because of their declarative nature. So i decided to try to create my own library. The result is mkup, which you can find as open source project at google code: http://code.google.com/p/mkup/.
You can try out all examples listed here inside your browser using the mkup workbench: http://mkup.googlecode.com/svn/trunk/workbench.html.
Design goals
Mkup was written with some things in mind that make a node builder useful.
- code should reflect what is being built
- easy access to the nodes created
- code should be as short as possible
Target one: code should reflect what is being built
This code:
var mkup = Mkup.mkup($('results'));
mkup
.div()
.childSpan('note_this')
.text('Inside Span')
.write();
creates the following nodes:
<div> <span class="note_this">Inside Span</span> </div>
As you can see calls to mkup are designed to be chained. This removes clutter when specifying what should be done. Of course, chaining is optional, to make using mkup with loops comfortable:
var mkup = Mkup.mkup($('results'));
mkup.ul().child();
for(var i=0; i<3;i++){
mkup.li().text('Item #'+i);
}
mkup.write();
creates:
<ul> <li>Item #0</li> <li>Item #1</li> <li>Item #2</li> </ul>
Target two: easy access to nodes created
After building up the nodes you need, getting a reference to one ore more nodes just created is often needed to -for example- change node contents or add listeners. This can be done using mkup:
var mkup = Mkup.mkup($('results'));
mkup
.div()
.childA({href:"#"},"link")
.text("Trigger some fancy stuff");
var createdNodes = mkup.write();
createdNodes.link.observe("click", function(event){
Event.stop(event);
alert("Fancy! Wow!");
});
creates:
<div> <a href="#">Trigger some fancy stuff</a> </div>
Target three: code should be as short as possible
Well judge yourself:
Without mkup:
var div = new Element("div");
var link = new Element("a",{href:"#"});
div.appendChild(link);
link.appendChild(document.createTextNode("Link"));
$('results').appendChild(div);
using mkup:
var mkup = Mkup.mkup($('results'));
mkup.div().childA({href:"#"}).text("Link").write();
How to help
If you are interested in mkup, you can help us to improve it:
- tell us that you use it – because it’s motivating to know that mkup is useful to someone
- tell the world that you use it – see above
- run the test suite in your browser and report bugs here – you can find the test page here
- add a feature – mkup is a small project, so this is your chance to participate in a open source project without a steep learning curve. Checking out the code using subversion is easy and explained here
How about, it’s only one line & I don’t need your lib:
$('results').html('Link');
It’s pretty sad to see libraries created around things as pointless as this. Really, come on.
The key point for me are the references to the elements. Yes you can also use innerHTML and build everything as string, but how to register listeners to inner elements. Assign everything an id and reparse the DOM doesn’t feel right.
With mkup you get the references to every element you like inside your created DOM tree. This removes long cascades of “new Element()” and “appendChild()”.
jQuerys html() is just a kind of wrapper of innerHTML isn’t it?
Well yes, just use
innerHTMLand you don’t even need to use jQuery anymore :-)There are at least two points that come to my mind that jQuery’s
html()function does not:I see that it is pointless to use mkup when
innerHTMLdoes the job, but mkup does more than just creating nodes.So thank you for pointing out that using mkup without needing what is does is pointless :-)