React-like DOM construction in 8 lines.
Tl;Dr
var $text = document.createTextNode.bind(document);
var $comment = document.createComment.bind(document);
var $html = function (tag, attrs, c) {
var el = document.createElement(tag);
for (var k in attrs) attrs.hasOwnProperty(k) && el.setAttribute(k, attrs[k]);
for (var i = 0; i < (c ? c.length : 0); i++) el.appendChild(c[i]);
return el;
};
Usage
A lot of people recommend using JSX when creating React components. I think that's a good recommendation, especially if you have designers mucking around in your components. However, I find the declarative syntax of React.createElement
to be quite pleasant to work with.
This is a minimalistic implementation of similar syntax; simple, terse DOM construction in JavaScript.
var el = $html('div', { class: 'foo bar' }, [
$html('h1', null, [$text('Hello World')]),
$text('Lorem ipsum dolor sit amet!'),
]);
document.body.appendChild(el);
Will create the following DOM:
<div class="foo bar">
<h1>Hello World</h1>
Lorem ipsum dolor sit amet!
</div>
It makes simple work of transforming lists into DOM using .map()
.
var data = [
/*...*/
];
function renderItem(item) {
return $html('div', { id: item.id }, [$text(item.name)]);
}
var results = $html('div', { class: 'result' }, elements);
Good for What?
Mostly, I've used this when I need to quickly generate some dynamic DOM where a full-fleged templating engine feels like overkill.
I've used this little function in a few CodePen prototypes and sketches. Most recently, I've used it for defining Knockout Components.
It's worked pretty smoothly so far; but will eventually be replaced with a proper templating engine.Ko
component templates can be document fragments or array of DOM nodes.
Lastly, sometimes string
concat-ing and finally injecting/parsing--like Handlebars--feels a little obtuse for the type of transformations I want to do.