Skip to content

Instantly share code, notes, and snippets.

@SeanJM
Last active March 14, 2016 15:15
Show Gist options
  • Select an option

  • Save SeanJM/8f9ba020bf28fd311984 to your computer and use it in GitHub Desktop.

Select an option

Save SeanJM/8f9ba020bf28fd311984 to your computer and use it in GitHub Desktop.
/*
createNode(tagNameOrNode, attributes, callback(createNode))
eg >
createNode('div', {
class : 'my-class-name'
}, function (newNode) {
});
returns a list of chained methods
- .append(Node)
*/
function createNode(tagNameOrNode, opt, callback) {
var node, k, i, $node;
var numberProperties = [
'z-index',
'opacity'
];
var dimensions = [
'height',
'width',
'left',
'top',
'bottom',
'right'
];
var toPixel = [
'bottom',
'fontSize',
'height',
'left',
'marginBottom',
'marginLeft',
'marginRight',
'marginTop',
'minHeight',
'minWidth',
'paddingBottom',
'paddingLeft',
'paddingRight',
'paddingTop',
'right',
'top',
'width',
];
var defaultStyles = [
'auto',
'none'
];
var length = 0;
var childNodes = [];
function getDimension(target, type) {
var styles = window.getComputedStyle(target);
var inBody = document.body.contains(target);
if (inBody && typeof styles[type] === 'string' && defaultStyles.indexOf(styles[type]) === -1) {
if (styles[type].indexOf('px') !== -1) {
dimensions[type] = parseInt(styles[type], 10);
}
} else if (inBody) {
dimensions[type] = target.getBoundingClientRect()[type];
} else {
clone = target.cloneNode(true);
clone.left = '10000px';
document.body.appendChild(clone);
dimensions[type] = getDimension(clone, type);
document.body.removeChild(clone);
}
return dimensions[type];
}
function setDimension(type, value) {
var clone;
var parentWidth;
if (typeof value === 'number') {
dimensions[type] = value;
value = value + 'px';
} else {
dimensions[type] = parseInt(value, 10);
}
node.style[type] = value;
return $node;
}
function toStyleString(styleObject) {
var string = '';
var property;
var value;
for (property in styleObject) {
if (styleObject.hasOwnProperty(property)) {
value = styleObject[property];
if (dimensions.indexOf(property) !== -1) {
dimensions[property] = value;
}
if (typeof value === 'number' && numberProperties.indexOf(property) === -1) {
value += 'px';
}
string += property + ': ' + value + ';';
}
}
return string;
}
$node = {
attr : function (property, value) {
if (typeof value === 'undefined') {
return node.getAttribute(property);
}
node.setAttribute(property, value);
},
clientRect : function () {
return node.getBoundingClientRect();
},
centerTo : function (targetNode) {
var nodeRect = $node.clientRect();
var width = nodeRect.width;
var height = nodeRect.height;
var targetIsParent;
var targetRect = {};
if (targetNode === window) {
targetRect.width = window.innerWidth;
targetRect.height = window.innerHeight;
targetIsParent = true;
} else if (typeof targetNode.node === 'object') {
targetRect = targetNode.node.getBoundingClientRect();
targetIsParent = targetNode.node.contains(node);
} else {
targetRect = targetNode.getBoundingClientRect();
targetIsParent = targetNode.contains(node);
}
if (targetIsParent) {
$node.style('left', (targetRect.width / 2) - (width / 2));
$node.style('top', (targetRect.height / 2) - (height / 2));
} else {
$node.style('left', targetRect.left + (targetRect.width / 2) - (width / 2));
$node.style('top', targetRect.top + (targetRect.height / 2) - (height / 2));
}
return $node;
},
length : function () {
return length;
},
append : function () {
var n = arguments.length;
var a = new Array(n);
var i;
var $childNode;
for (i = 0; i < n; i++) {
a[i] = arguments[i];
}
if (typeof a[0] === 'object' && typeof a[0].append === 'function') {
$childNode = a[0];
if (typeof a[1] === 'function') {
a[1](a[0]);
}
} else {
$childNode = createNode.apply(null, a);
}
length += 1;
$childNode.parent = $node;
childNodes.push($childNode);
node.appendChild($childNode.node);
return $node;
},
appendTo : function (target) {
if (typeof target.node === 'object') {
target.append(node);
} else {
target.appendChild(node);
}
return $node;
},
children : function () {
return childNodes;
},
addClass : function (className) {
var c = node.className.split(' ');
var i = c.indexOf(className);
if (i === -1) {
node.className = c.concat(className).join(' ');
}
return $node;
},
removeClass : function (className) {
var c = node.className.split(' ');
var i = c.indexOf(className);
if (i !== -1) {
c.splice(i, 1);
node.className = c.join(' ');
}
return $node;
},
disable : function () {
node.setAttribute('disabled', 'disabled');
return $node;
},
enable : function () {
node.removeAttribute('disabled');
return $node;
},
on : function (name, callback) {
name.split(',').forEach(function (n) {
node.addEventListener(n.trim(), callback, false);
});
return $node;
},
off : function (name, callback) {
name.split(',').forEach(function (n) {
node.removeEventListener(n.trim(), callback, false);
});
return $node;
},
trigger : function (name) {
if (node.getAttribute('disabled') !== 'disabled') {
node.dispatchEvent(new Event(name));
}
return $node;
},
text : function (value) {
node.innerHTML = value;
return $node;
},
value : function (value) {
if (typeof value !== 'undefined') {
node.value = value;
return $node;
}
return node.value;
},
removeNode : function () {
node.parentNode.removeChild(node);
return $node;
},
opacity : function (value) {
node.style.opacity = value;
return $node;
},
style : function (name, value) {
var v;
if (typeof value === 'undefined' && dimensions.indexOf(name) === -1) {
v = window.getComputedStyle(node)[name];
return v.substr(-2) === 'px' ? parseFloat(v, 10) : v;
} else if (typeof value === 'undefined') {
return getDimension(node, name);
}
if (typeof createNode.prefix[name] === 'string') {
name = createNode.prefix[name];
}
if (toPixel.indexOf(name) !== -1 && !isNaN(Number(value))) {
node.style[name] = value.toString().substr(-2) === 'px' ? value : value + 'px';
} else {
node.style[name] = value;
}
if (dimensions.indexOf(name) !== -1) {
setDimension(name, value);
}
return $node;
},
position : function (value) {
node.style.position = value;
return $node;
},
replaceWith : function (newNode) {
node.parentNode.replaceChild(newNode.node, node);
node = newNode.node;
$node.node = newNode.node;
return $node;
},
scale : function (x, y) {
var computed = window.getComputedStyle(node)[createNode.prefix.transform];
var matrix = [];
if (computed === 'none') {
matrix = [
1, 0, 0,
1, 0, 0,
];
} else {
matrix = computed.slice(7, -1).split(',').map(function (a) {
return Number(a);
});
}
if (typeof y === 'undefined') {
y = x;
}
matrix[0] = x;
matrix[3] = y;
node.style[createNode.prefix.transform] = 'matrix(' + matrix.join(',') + ')';
},
focus : function () {
node.focus();
return $node;
},
select : function (start, end) {
if (typeof start === 'undefined' && typeof end === 'undefined') {
return [ node.selectionStart, node.selectionEnd ];
}
node.focus();
node.setSelectionRange(start, end === -1 ? node.value.length : end);
return $node;
}
};
if (typeof tagNameOrNode === 'string') {
node = document.createElement(tagNameOrNode);
} else if (typeof tagNameOrNode === 'object' && typeof tagNameOrNode.nodeType === 'number') {
node = tagNameOrNode;
}
$node.node = node;
for (k in opt) {
if (k === 'class') {
node.className = opt[k];
} else if (k === 'text') {
node.innerHTML = opt[k];
} else if (k === 'style') {
node[k] = toStyleString(opt[k]);
} else {
node[k] = opt[k];
}
}
if (typeof callback === 'function') {
callback($node);
}
return $node;
}
(function () {
var styles = window.getComputedStyle(document.body);
var arr = ['transform'];
var prefix = ['Moz', 'webkit', 'ms'];
var property;
createNode.prefix = {};
for (var i = 0, n = prefix.length; i < n; i++) {
for (var x = 0, y = arr.length; x < y; x++) {
property = prefix[i] + arr[x][0].toUpperCase() + arr[x].slice(1);
if (typeof styles[property] !== 'undefined') {
createNode.prefix[arr[x]] = property;
}
}
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment