Created
July 12, 2016 21:30
-
-
Save justinbmeyer/147f6d536b41aaf63f9af806d260516e to your computer and use it in GitHub Desktop.
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() { | |
$ = function(selector) { | |
if( !(this instanceof $)) { | |
return new $(selector); | |
} | |
var elements; | |
if(typeof selector === "string") { | |
elements = document.querySelectorAll(selector); | |
} else if( isArrayLike(selector) ){ | |
elements = $.makeArray(selector); | |
} else { | |
elements = [selector]; | |
} | |
[].push.apply(this, elements); | |
}; | |
$.extend = function(target, object) { | |
for(var prop in object) { | |
if(object.hasOwnProperty(prop)) { | |
target[prop] = object[prop] | |
} | |
} | |
return target; | |
}; | |
// Static methods | |
var isArrayLike = function(obj) { | |
if(typeof obj.length === "number") { | |
if(obj.length === 0) { | |
return true; | |
} else if(obj.length > 0) { | |
return (obj.length - 1) in obj; | |
} | |
} | |
}; | |
$.extend($, { | |
isArray: function(obj) { | |
return Object.prototype.toString.call(obj) === "[object Array]"; | |
}, | |
each: function(collection, cb) { | |
if(isArrayLike(collection)) { | |
for(var i = 0; i < collection.length; i++) { | |
if( cb(i, collection[i]) === false) { | |
break; | |
} | |
} | |
} else { | |
for( var prop in collection) { | |
if(collection.hasOwnProperty(prop)) { | |
if( cb(prop, collection[prop]) === false) { | |
break; | |
} | |
} | |
} | |
} | |
return collection; | |
}, | |
// makeArray({one: "a", two: "b"}) //-> ["a","b"] | |
makeArray: function(arr) { | |
var array = []; | |
Array.prototype.push.apply(array, arr); | |
return array; | |
}, | |
proxy: function(fn, context) { | |
return function(){ | |
return fn.apply(context, arguments); | |
}; | |
} | |
}); | |
var makeSimpleGetterSetter = function(propName){ | |
return function(newVal){ | |
if(arguments.length) { | |
// setter | |
return $.each(this, function(index, element){ | |
element[propName] = newVal; | |
}); | |
} else { | |
// getter | |
if(this[0]) { | |
return this[0][propName]; | |
} | |
} | |
} | |
}; | |
var getText = function(node) { | |
var text = ""; | |
$.each(node.childNodes, function(i, child){ | |
if(child.nodeType === Node.TEXT_NODE) { | |
text += child.nodeValue; | |
} else { | |
text += getText(child); | |
} | |
}); | |
return text; | |
}; | |
var makeTraverser = function(fn){ | |
return function(){ | |
var elements = []; | |
var args = arguments; | |
$.each(this, function(i, element){ | |
var result = fn.apply(element,args); | |
if(result) { | |
if(isArrayLike(result)) { | |
elements.push.apply(elements, result); | |
} else { | |
elements.push(result); | |
} | |
} | |
}); | |
return $(elements); | |
}; | |
}; | |
var makeSibling = function(propName){ | |
return function(){ | |
var cur = this[propName]; | |
while(cur && cur.nodeType !== Node.ELEMENT_NODE) { | |
cur = cur[propName]; | |
} | |
return cur; | |
}; | |
}; | |
$.extend($.prototype, { | |
html: makeSimpleGetterSetter("innerHTML"), | |
val: makeSimpleGetterSetter("value"), | |
text: function(newText) { | |
if(arguments.length) { | |
this.html(""); | |
return $.each(this, function(i, element){ | |
var text = document.createTextNode(newText); | |
element.appendChild(text); | |
}); | |
} else { | |
return getText(this[0]); | |
} | |
}, | |
find: makeTraverser(function(selector){ | |
return this.querySelectorAll(selector); | |
}), | |
next: makeTraverser(makeSibling("nextSibling")), | |
prev: makeTraverser(makeSibling("previousSibling")), | |
parent: makeTraverser(function() { | |
return this.parentNode; | |
}), | |
children: makeTraverser(function(){ | |
return this.children; | |
}), | |
attr: function(attrName, value) {}, | |
css: function(cssPropName, value) {}, | |
width: function() {}, | |
offset: function() { | |
var offset = this[0].getBoundingClientRect(); | |
return { | |
top: offset.top + window.pageYOffset, | |
left: offset.left + window.pageXOffset | |
}; | |
}, | |
hide: function() {}, | |
show: function() {}, | |
// Events | |
bind: function(eventName, handler) {}, | |
unbind: function(eventName, handler) {}, | |
has: function(selector) { | |
var elements = []; | |
$.each(this, function(i, el) { | |
if(el.matches(selector)) { | |
elements.push(el); | |
} | |
}); | |
return $( elements ); | |
}, | |
on: function(eventType, selector, handler) { | |
return this.bind(eventType, function(ev){ | |
var cur = ev.target; | |
do { | |
if ($([ cur ]).has(selector).length) { | |
handler.call(cur, ev); | |
} | |
cur = cur.parentNode; | |
} while (cur && cur !== ev.currentTarget); | |
}); | |
}, | |
off: function(eventType, selector, handler) {}, | |
data: function(propName, data) {}, | |
// Extra | |
addClass: function(className) {}, | |
removeClass: function(className) {}, | |
append: function(element) {} | |
}); | |
$.buildFragment = function(html) {}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment