Better than templates

fgnass 22 February 2012

When I saw a project called Jade for jQuery being featured on DailyJS yesterday I thought I should take the time and promote my lightweight Jade/HAML-style DOM builder I wrote some month ago.

In his jQuery Roundup Alex Young writes about jQuery and Jade:

Seeing as both of these technologies are all about CSS selectors, I’ve always felt like it makes sense to use them together.

I agree that using CSS selectors not only to query but also to create elements makes a lot of sense. But using a rather huge templating library like Jade on the client feels just wrong.

What I wanted instead was a jQuery-flavored wrapper around the native DOM API that made it easy to create DOM trees leveraging CSS selectors the same way Jade and HAML do.

Neil Jenkins makes some excellent points why using the DOM instead of templates is a good idea:

  • No need to query the DOM, as you can just save references to nodes you’ll need later as you create them
  • No escaping worries; zero chance of XSS bugs
  • JSHint will validate your syntax
  • Flexibility to use the full power of JS; easily call other functions to generate parts of your DOM tree

He has also written a JsPerf test that shows that using the DOM API is up to 50% faster than using innerHTML in modern browsers.

Let’s build some elements m’kay

M’kay is a tiny (556 bytes) plugin for jQuery or Zepto.js. You can use it like this:

var items = 'Click on one of these'.split(' ');

$('body').mk('#message')
  .mk('a.big', "M'kay on GitHub").attr('href', 'https://github.com/fgnass/mkay')._
  .mk('ul', $.map(items, function(text) {
      return $.mk('li.item', text).click(function() {
        alert(text);
      });
  }));

This will generate the following HTML and add a click listener to each item:

<div id="message">
  <a class="big" href="https://github.com/fgnass/mkay">M'kay on GitHub</a>
  <ul>
    <li class="item">Click</li>
    <li class="item">on</li>
    <li class="item">one</li>
    <li class="item">of</li>
    <li class="item">these</li>
  </ul>
</div>

You can play with the example above here on JsFiddle. For sources, tests and documentation please refer to the GitHub project page.