Skip to content

Instantly share code, notes, and snippets.

@jareware
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jareware/8dc0cc1a948c122edce0 to your computer and use it in GitHub Desktop.
Save jareware/8dc0cc1a948c122edce0 to your computer and use it in GitHub Desktop.
Utility function for generating HTML/XML DOM trees in the browser.
/**
* Utility function for generating HTML/XML DOM trees in the browser.
*
* Returns a node with the given name. The rest are var-args, so that:
*
* - an object sets attributes as key/value-pairs
* - a string/number/boolean sets the text content of the node
* - a node is treated as a child node
* - an array is treated as a list of child nodes
*
* For convenience, falsy values in the list of children are ignored.
*
* There's three special cases for the name argument:
*
* - when "", a text node is created, with content from the 2nd arg
* - when "<!", a comment node is created, with content from the 2nd arg
* - when an existing node, that node is used instead of creating a new one
*
* @example el('p',
* el('<!', 'this is a comment'),
* el('a', 'Click here', {
* href: '#some-location'
* }),
* el('', 'Text after link')
* );
*
* @example el('ul',
* [ 1, 2, 3, 4, 5 ].map(function(i) {
* if (i % 2) return el('li', i);
* })
* );
*
* @example el(document.querySelector('#existing-root'),
* el('p', 'New node added under root')
* );
*
* @returns https://developer.mozilla.org/en-US/docs/Web/API/element
*
* @link https://gist.github.com/jareware/8dc0cc1a948c122edce0
* @author Jarno Rantanen <jarno@jrw.fi>
* @license Do whatever you want with it
*/
function el(name) {
function isNode(n) {
return typeof n === 'object' && n.nodeType && n.nodeName;
}
if (name === '<!') {
return document.createComment(arguments[1]);
} else if (name === '') {
return document.createTextNode(arguments[1]);
}
var node = isNode(name) ? name : document.createElement(name);
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
if (arg instanceof Array) {
arg.forEach(function(child) {
child && node.appendChild(child);
});
} else if (typeof arg === 'object') {
if (isNode(arg)) {
node.appendChild(arg);
} else {
Object.keys(arg).forEach(function(key) {
node.setAttribute(key, arg[key]);
});
}
} else if ([ 'string', 'number', 'boolean' ].indexOf(typeof arg) >= 0) {
node.textContent = arg;
}
});
return node;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment