-
-
Save panayotoff/4c13f66953f06907317a to your computer and use it in GitHub Desktop.
x.js is my first attempt to build jQuery-like micro library. It has most of the functionality you use every day - selectors, events, traversal, add/remove/toggle class, get/set attributes and handles most common cases.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
(function (window) { | |
'use strict'; | |
var xBuild = (function () { | |
var xGlobals = { | |
newElementRegex: /<(\w+)\s?\/>/, | |
}; | |
var x = function (_expression, _context) { | |
return new x.fn.init(_expression, _context); | |
}; | |
//-------------------------------------------------------------- | |
// Extending X with util functions | |
//-------------------------------------------------------------- | |
x.addHelper = function (_name, _fn) { | |
x[_name] = _fn; | |
}; | |
//-------------------------------------------------------------- | |
// Simple get request helper, just an example how to add helpers | |
//-------------------------------------------------------------- | |
x.addHelper('get', function (_url, _onDone, _onFail) { | |
var request = new XMLHttpRequest(); | |
request.open('GET', _url, true); | |
request.onload = function () { | |
if (request.status >= 200 && request.status < 400) { | |
_onDone(request.responseText); | |
} else { | |
_onFail(request.responseText) | |
} | |
}; | |
request.onerror = _onFail; | |
request.send(); | |
}); | |
//-------------------------------------------------------------- | |
// Build prop is used internally | |
//-------------------------------------------------------------- | |
x.addHelper('buildProp', function (_prop, _val) { | |
var props = {}; | |
if (_val !== undefined) { | |
props[_prop] = _val; | |
} else { | |
props = _prop; | |
} | |
return props; | |
}); | |
//-------------------------------------------------------------- | |
// Core | |
//-------------------------------------------------------------- | |
x.fn = x.prototype = { | |
init: function (_expression, _context) { | |
if (typeof _expression === 'function') { | |
document.addEventListener('DOMContentLoaded', _expression); | |
} else { | |
this.elements = []; | |
var newElement = xGlobals.newElementRegex.exec(_expression); | |
if (newElement) { | |
this.elements.push(document.createElement(newElement[1])); | |
} else if (_expression.tagName) { | |
this.elements.push(_expression); | |
} else if (_expression.constructor === Array) { | |
this.elements = _expression; | |
} else { | |
var nodes = (_context == null ? document : _context).querySelectorAll(_expression); | |
for (var i = 0, j = nodes.length; i < j; i++) { | |
this.elements.push(nodes[i]); | |
} | |
} | |
return this; | |
} | |
}, | |
el: function () { | |
return this.first().elements[0]; | |
}, | |
forEach: function (_fn) { | |
this.elements.forEach(_fn); | |
return this; | |
}, | |
on: function (_handler, _fn) { | |
return this.forEach(function (el) { | |
el.addEventListener(_handler, _fn); | |
}); | |
}, | |
off: function (_handler, _fn) { | |
return this.forEach(function (el) { | |
el.removeEventListener(_handler, _fn); | |
}); | |
}, | |
trigger: function (_event, _data) { | |
return this.forEach(function (elem) { | |
elem.dispatchEvent(new CustomEvent(_event, {detail: _data || {}})) | |
}); | |
}, | |
addClass: function (_className) { | |
return this.forEach(function (elem) { | |
elem.classList.add(_className); | |
}); | |
}, | |
removeClass: function (_className) { | |
return this.forEach(function (elem) { | |
elem.classList.remove(_className); | |
}); | |
}, | |
toggleClass: function (_className) { | |
return this.forEach(function (elem) { | |
elem.classList.toggle(_className); | |
}); | |
}, | |
hasClass: function (_className) { | |
var hasClass = false; | |
this.forEach(function (elem) { | |
if (elem.classList.contains(_className)) { | |
hasClass = true; | |
} | |
}); | |
return hasClass; | |
}, | |
text: function (_newText) { | |
if (_newText === undefined) { | |
return this.el().textContent; | |
} | |
return this.forEach(function (elem) { | |
elem.innerText = _newText; | |
}); | |
}, | |
html: function (_newHtml) { | |
if (_newHtml === undefined) { | |
return this.el().innerHTML; | |
} | |
return this.forEach(function (elem) { | |
elem.innerHTML = _newHtml; | |
}); | |
}, | |
find: function (_selector) { | |
var elements = []; | |
this.forEach(function (elem) { | |
var finds = elem.querySelectorAll(_selector); | |
if (finds.length) { | |
for (var i = 0, j = finds.length; i < j; i++) { | |
elements.push(finds[i]); | |
} | |
} | |
}); | |
return x(elements); | |
}, | |
empty: function () { | |
return this.html(''); | |
}, | |
remove: function () { | |
return this.forEach(function (elem) { | |
elem.parentNode.removeChild(elem); | |
}); | |
}, | |
//Need to implement those; | |
append: function (_elem) { | |
}, | |
prepend: function (_elem) { | |
}, | |
before: function (_elem) { | |
}, | |
after: function (_elem) { | |
}, | |
clone: function () { | |
return this.el().cloneNode(true); | |
}, | |
attr: function (_attrName, _attrVal) { | |
if (_attrVal === undefined) { | |
return this.el().getAttribute(_attrName); | |
} | |
var attrObj = x.buildProp(_attrName, _attrVal); | |
this.forEach(function (elem) { | |
for (var attr in attrObj) { | |
if (attrObj.hasOwnProperty(attr)) { | |
elem.setAttribute(attr, attrObj[attr]); | |
} | |
} | |
}); | |
return this; | |
}, | |
css: function (_cssObj, _cssVal) { | |
var stylesObj = x.buildProp(_cssObj, _cssVal); | |
return this.forEach(function (elem) { | |
for (var rule in stylesObj) { | |
if (stylesObj.hasOwnProperty(rule)) { | |
elem.style[rule] = stylesObj[rule]; | |
} | |
} | |
}); | |
}, | |
parent: function () { | |
return x(this.el().parentNode); | |
}, | |
first: function () { | |
return this.eq(0); | |
}, | |
last: function () { | |
return this.eq(this.elements.length - 1); | |
}, | |
eq: function (_index) { | |
return x(this.elements[_index]); | |
} | |
}; | |
//-------------------------------------------------------------- | |
// Expose to global | |
//-------------------------------------------------------------- | |
x.fn.init.prototype = x.fn; | |
window.x = x; | |
})(); | |
})(window, undefined); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment