kareem-h
8/4/2016 - 6:26 PM

createElement.js // a 300 byte DOM Element creator

createElement.js // a 300 byte DOM Element creator

(function(e){var t="(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)",n="^(?:"+t+")|^#"+t+"|^\\."+t+"|^\\["+t+"(?:([*$|~^]?=)([\"'])((?:(?=(\\\\?))\\8.)*?)\\6)?\\]";document.createElement=function(t){for(var r=e.call(this,"div"),i,s="";t&&(i=t.match(n));){if(i[1])r=e.call(this,i[1]);if(i[2])r.id=i[2];if(i[3])s+=" "+i[3];if(i[4])r.setAttribute(i[4],i[7]||"");t=t.slice(i[0].length)}if(s)r.className=s.slice(1);return r}})(document.createElement)
(function (createElement) {
	var
	MATCH = '(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)',
	REGEX = '^(?:' + MATCH + ')|^#' + MATCH + '|^\\.' + MATCH + '|^\\[' + MATCH + '(?:([*$|~^]?=)(["\'])((?:(?=(\\\\?))\\8.)*?)\\6)?\\]';

	document.createElement = function (selector) {
		for (var node = createElement.call(this, 'div'), match, className = ''; selector && (match = selector.match(REGEX));) {
			if (match[1]) node = createElement.call(this, match[1]);
			if (match[2]) node.id = match[2];
			if (match[3]) className += ' ' + match[3];
			if (match[4]) node.setAttribute(match[4], match[7] || '');

			selector = selector.slice(match[0].length);
		}

		if (className) node.className = className.slice(1);

		return node;
	};
})(document.createElement);
(function(e){"use strict";var t="(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)",n="([\"'])((?:(?=(\\\\?))\\",r="[\\W\\w])*?)\\",i="^(?:"+t+")|^#"+t+"|^\\."+t+"|^\\["+t+"(?:([*$|~^]?=)"+n+"8"+r+"6"+")?\\]|^\\s*[\\n\\r]+([\\t]*)\\s*|^(\\s+)|^"+n+"13"+r+"11";document.createElement=function(t){var n=t.replace(/^\s+|\s+$/),r=document.createDocumentFragment(),s=[r,e.call(this,"div")];for(var o=r,u=o.appendChild(s[1]),a=1,f=true,l;n&&(l=n.match(i));){if(l[1]){o.replaceChild(u=e.call(this,l[1]),o.lastChild);if(f)s[a]=u}if(l[2])u.id=l[2];if(l[3])u.className+=(u.className?" ":"")+l[3];if(l[4])u.setAttribute(l[4],l[7]||"");if(l[9]!==undefined){a=l[9].length;o=s[a];u=s[++a]=o.appendChild(e.call(this,"div"))}if(l[10]){o=u;u=o.appendChild(e.call(this,"div"));f=false}if(l[11]){o.replaceChild(u=document.createTextNode(l[12]),o.lastChild);if(f)s[a]=u}n=n.slice(l[0].length)}return r.childNodes.length===1?r.lastChild:r}})(document.createElement)
(function (createElement) {
	'use strict';

	var
	MATCH = '(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)',
	QUOTE1 = '(["\'])((?:(?=(\\\\?))\\',
	QUOTE2 = '[\\W\\w])*?)\\',
	REGEX = '^(?:' + MATCH + ')|^#' + MATCH + '|^\\.' + MATCH + '|^\\[' + MATCH + '(?:([*$|~^]?=)' + QUOTE1 + '8' + QUOTE2 + '6' + ')?\\]|^\\s*[\\n\\r]+([\\t]*)\\s*|^(\\s+)|^' + QUOTE1 + '13' + QUOTE2 + '11';

	document.createElement = function (selectorUntrimmed) {
		var
		selector = selectorUntrimmed.replace(/^\s+|\s+$/),
		root = document.createDocumentFragment(),
		nest = [root, createElement.call(this, 'div')];

		for (var frag = root, node = frag.appendChild(nest[1]), index = 1, first = true, match; selector && (match = selector.match(REGEX));) {
			// tag
			if (match[1]) {
				frag.replaceChild(node = createElement.call(this, match[1]), frag.lastChild);

				if (first) nest[index] = node;
			}
			// id
			if (match[2]) node.id = match[2];
			// class
			if (match[3]) node.className += (node.className ? ' ' : '') + match[3];
			// attribute
			if (match[4]) node.setAttribute(match[4], match[7] || '');
			// nesting
			if (match[9] !== undefined) {
				index = match[9].length;

				frag = nest[index];
				node = nest[++index] = frag.appendChild(createElement.call(this, 'div'));
			}
			// child 
			if (match[10]) {
				frag = node;
				node = frag.appendChild(createElement.call(this, 'div'));

				first = false;
			}
			// text
			if (match[11]) {
				frag.replaceChild(node = document.createTextNode(match[12]), frag.lastChild);

				if (first) nest[index] = node;
			}

			selector = selector.slice(match[0].length);
		}

		return root.childNodes.length === 1 ? root.lastChild : root;
	};
})(document.createElement);

createElement.js

createElement.js lets document.createElement use CSS selectors.

This is a pretty useful library for building out DOM elements. The whole thing runs on one regex and a for loop, so it’s plenty fast. The script is 300 bytes when compressed and gzipped. For 524 bytes (advanced), it includes nesting support and can generate entire DOM hierarchies, including text nodes.

Usage

document.createElement(); // generates <div />

document.createElement('li'); // generates <li />

document.createElement('#foo'); // generates <div id="foo" />
document.createElement('.bar'); // generates <div class="bar" />
document.createElement('.alpha.omega'); // generates <div class="alpha omega" />

document.createElement('[tabindex]'); // generates <div tabindex />
document.createElement('[title="Hello"]'); // generates <div title="Hello" />

document.createElement('p.this#thing.also[data-amen].that'); // generates <p id="thing" class="this also that" data-amen />

document.createElement('[data-value="<.it=\"#works[well]\">"]'); // generates <div data-value="&lt;.it=&quot;#works[well]&quot;&gt;" />

Advanced usage

document.createElement('span.field\n\tlabel "To: "\n\t\tinput'); // generates <span class="field"><label>To: <input></label></span>

Compatibility

Works in everything since IE6.