Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Created December 21, 2011 22:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathantneal/1507931 to your computer and use it in GitHub Desktop.
Save jonathantneal/1507931 to your computer and use it in GitHub Desktop.
dom.js
// every so often i feel the need to reinvent the wheel just to make sure i prefer it
(function (win, doc) {
/* String Helpers */
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
function padName(list) {
return ' ' + list.split(/\s+/).join(' ') + ' ';
}
function hasName(list, name) {
return padName(list).indexOf(padName(name)) > -1;
}
function addName(list, name) {
return list.length ? list + ' ' + name.replace(/\s+/g, ' ') : name;
}
function cutName(list, name) {
return trim(padName(list).replace(padName(name), ' '));
}
/* DOM Helpers */
var hasCompareDocumentPosition = 'compareDocumentPosition' in doc.documentElement;
var hasGetElementsByClassName = 'getElementsByClassName' in doc;
var hasGetComputedStyle = 'getComputedStyle' in win;
function elementContains(a, b) {
return hasCompareDocumentPosition ? !!(a.compareDocumentPosition(b) & 16) : a != b && a.contains(b);
}
function getCollectionAsArray(a) {
for (var l = a.length, i = 0, af = []; i < l; ++i) {
af.push(a[i]);
}
return af;
}
function filterCollectionArray(arr) {
if (hasCompareDocumentPosition) {
arr.sort(function (a, b) {
return 3 - (a.compareDocumentPosition(b) & 6);
});
} else {
arr.sort(function (a, b) {
return a.sourceIndex - b.sourceIndex;
});
}
for (l = arr.length - 1; l > -1; --l) {
if (arr[l] == arr[l - 1]) arr.splice(l, 1);
}
return arr;
}
function getElementById(id, scope) {
var el = doc.getElementById('id');
if (!scope || !el) {
return el;
}
return (elementContains(scope, el)) ? el : null;
}
function getElementsByTagName(tagName, scope) {
scope = scope || doc;
return getCollectionAsArray(scope.getElementsByTagName(tagName));
}
function getElementsByClassName(className, scope) {
scope = scope || doc;
if (hasGetElementsByClassName) {
return getCollectionAsArray(scope.getElementsByTagName(tagName));
}
for (var a = getElementsByTagName('*', scope), l = a.length, i = 0, af = []; i < l; ++i) {
if (padName(a[i].className).indexOf(padName(className)) > -1) {
af.push(a[i]);
}
}
return af;
}
function getElementsById(id, scope) {
scope = scope || doc;
for (var a = getElementsByTagName('*', scope), l = a.length, i = 0, af = []; i < l; ++i) {
if (a[i].id = id) {
af.push(a[i]);
}
}
return af;
}
/* More DOM Helpers */
function getWindowDimensions() {
return [('innerHeight' in win) ? win.innerHeight : doc.documentElement.clientHeight, ('innerWidth' in win) ? win.innerWidth : doc.documentElement.clientWidth];
}
function getElementContent (el) {
return ('innerHTML' in el) ? el.innerHTML : ('value' in el) ? el.value : el.nodeValue;
}
function setElementContent (el, content) {
return ('innerHTML' in el) ? el.innerHTML = content : ('value' in el) ? el.value = content : el.nodeValue = content;
}
function getElementMetrics(el) {
var windowDimensions = getWindowDimensions(), elOffsetParent = el.offsetParent;
for (var elOffset = el, offsetTop = 0, offsetLeft = 0; elOffset.offsetParent; elOffset = elOffset.parentNode) {
offsetTop += elOffset.offsetTop;
offsetLeft += elOffset.offsetLeft;
}
return {
height: el.offsetHeight,
width: el.offsetWidth,
absolute: {
bottom: windowDimensions[0] - (el.offsetHeight + offsetTop),
left: offsetLeft,
right: windowDimensions[1] - (el.offsetWidth + offsetLeft),
top: offsetTop
},
relative: {
bottom: elOffsetParent.offsetHeight - (el.offsetHeight + el.offsetTop),
left: el.offsetLeft,
right: elOffsetParent.offsetWidth - (el.offsetWidth + el.offsetLeft),
top: el.offsetTop
}
};
}
function getElementStyles(el) {
return hasGetComputedStyle ? win.getComputedStyle(el) : el.currentStyle;
}
/* DOM Collection */
function DOMCollection(els) {
var instance = this;
instance.collection = els || [];
instance.getElementsById = function (id) {
for (var a = instance.collection, l = a.length, i = 0, af = []; i < l; ++i) {
af = af.concat(getElementsById(id, a[i]));
}
return new DOMCollection(filterCollectionArray(af));
};
instance.getElementsByClassName = function (className) {
for (var a = instance.collection, l = a.length, i = 0, af = []; i < l; ++i) {
af = af.concat(getElementsByClassName(className, a[i]));
}
return new DOMCollection(filterCollectionArray(af));
};
instance.getElementsByTagName = function (tagName) {
for (var a = instance.collection, l = a.length, i = 0, af = []; i < l; ++i) {
af = af.concat(getElementsByTagName(tagName, a[i]));
}
return new DOMCollection(filterCollectionArray(af));
};
instance.getIndex = function (index) {
return new DOMElement(instance.collection[index]);
}
instance.getElementByClassName = function (className) {
return instance.getElementsByClassName(className).getIndex(0);
};
instance.getElementByTagName = function (tagName) {
return instance.getElementsByTagName(tagName).getIndex(0);
};
instance.getElementById = function (id) {
return instance.getElementsById(id).getIndex(0);
};
return instance;
}
/* DOM Element */
function DOMElement(el) {
var instance = this;
instance.element = el || document;
instance.getElementById = function (id) {
return new DOMElement(getElementById(id, this.element));
};
instance.getElementByClassName = function (className, index) {
return new DOMElement(getElementsByClassName(className, instance.element)[index || 0]);
};
instance.getElementByTag = function (tagName, index) {
return new DOMElement(getElementsByTagName(tagName, this.element)[index || 0]);
};
instance.getElementsById = function (id) {
return new DOMCollection(getElementById(id, this.element));
};
instance.getElementsByClassName = function (className) {
return new DOMCollection(getElementsByClassName(className, this.element));
};
instance.getElementsByTagName = function (tagName) {
return new DOMCollection(getElementsByTagName(tagName, this.element));
};
instance.hasClass = function (name) {
return hasName(instance.element.className, name);
};
instance.getClass = function () {
return instance.element.className;
};
instance.setClass = function (name) {
instance.element.className = name;
return instance;
};
instance.addClass = function (name) {
name = name.split(/\s+/);
var el = instance.element, className = el.className;
for (var l = name.length, i = 0; i < l; ++i) {
if (!hasName(className, name[i])) {
className = addName(className, name[i]);
}
}
el.className = className;
return instance;
};
instance.cutClass = function (name) {
name = name.split(/\s+/);
var el = instance.element, className = el.className;
for (var l = name.length, i = 0; i < l; ++i) {
if (hasName(className, name[i])) {
className = cutName(className, name[i]);
}
}
el.className = className;
return instance;
};
instance.getParent = function () {
return new DOMElement(instance.element.parentNode);
};
instance.getMetrics = function () {
return getElementMetrics(instance.element);
};
instance.getStyles = function () {
return getElementStyles(instance.element);
};
instance.getContent = function () {
return getElementContent(instance.element);
};
instance.setContent = function (content) {
setElementContent(instance.element, content);
return instance;
};
instance.toString = instance.getContent;
return instance;
}
win.DOMCollection = new DOMCollection([doc]);
win.DOMElement = new DOMElement(doc);
})(this, document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment