Skip to content

Instantly share code, notes, and snippets.

@MayankFawkes
Last active November 7, 2021 09:25
Show Gist options
  • Select an option

  • Save MayankFawkes/014868ea6420b5ea1656dbd358c07366 to your computer and use it in GitHub Desktop.

Select an option

Save MayankFawkes/014868ea6420b5ea1656dbd358c07366 to your computer and use it in GitHub Desktop.
A Simple clone of jQuery.
(function() {
var document = window.document;
var version = "0.1.0";
var arr = [];
var isFunction = function isFunction( obj ) {
return typeof obj === "function" && typeof obj.nodeType !== "number" &&
typeof obj.item !== "function";
};
var isWindow = function isWindow( obj ) {
return obj != null && obj === obj.window;
};
function isArrayLike(obj) {
let type = typeof obj;
if (obj instanceof Mscript) {
return true
}
if ( isFunction( obj ) || isWindow( obj ) ) {
return false;
}
if (Array.isArray) {
return Array.isArray(obj)
}
return obj.constructor.name === "Array" || obj.constructor.name.toLocaleLowerCase() === "array"
}
function Mscript(selector) {
return new Mscript.fn.init(selector)
}
Mscript.fn = Mscript.prototype = {
version: version,
constructor: Mscript,
length: 0,
ready: function(cb) {
const isReady = this.some(e => {
return e.readyState != null && e.readyState != "loading"
});
if (isReady) {
cb()
} else {
this.on("DOMContentLoaded", cb)
}
return this;
},
on: function(event, cbOrSelector, cb) {
if (typeof cbOrSelector === "function") {
this.forEach(e => e.addEventListener(event, cbOrSelector))
} else {
this.forEach(elem => {
elem.addEventListener(event, e => {
if (e.target.matches(cbOrSelector)) cb(e);
})
})
}
return this;
},
next: function() {
return this.map(e => e.nextElementSibling).filter(e => e != null);
},
prev: function() {
return this.map(e => e.previousElementSibling).filter(e => e != null);
},
push: arr.push,
sort: arr.sort,
splice: arr.splice,
some: arr.some,
indexOf: arr.indexOf,
forEach: arr.forEach,
};
if ( typeof Symbol === "function" ) {
Mscript.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}
init = Mscript.fn.init = function(selector) {
if ( selector == undefined ) {
return this;
}
if (isArrayLike(selector)){
return Mscript.makeArray(selector, this);
}else if (selector instanceof HTMLElement) {
this[0] = selector;
this.length = 1;
return this;
}else if (typeof selector === "string"){
if ( selector[ 0 ] === "<" &&
selector[ selector.length - 1 ] === ">" &&
selector.length >= 3 ) {
// make $(html) -> $(array)
}else{
node = document.querySelectorAll(selector);
if (node.length > 0) {
Mscript.makeArray(node, this);
}
}
}else if (typeof selector == "object"){
this[0] = selector;
this.length = 1;
}
return this;
}
init.prototype = Mscript.fn;
Mscript.extend = Mscript.fn.extend = function() {
var options, name, copy,
tmp = arguments[ 0 ],
i = 0,
length = arguments.length,
force = true,
target = this;
// Handle a deep copy situation
if ( typeof tmp === "boolean" ) {
force = tmp;
i++;
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( ( options = arguments[ i ] ) != null ) {
if (typeof options != "object"){
continue;
}
// Extend the base object
for ( name in options ) {
copy = options[ name ];
if (!isFunction(copy)){
continue;
}
// Prevent Object.prototype pollution
// Prevent never-ending loop
if ( name === "__proto__" || target === copy ) {
continue;
}
if (!force && this.hasOwnProperty(name)){
continue;
}
if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
// handle some external functions
Mscript.extend({
makeArray: function(arr, results) {
results = results || [];
if (typeof arr === "object") {
length = results.length || 0;
for (const [key, value] of Object.entries(arr)) {
results[parseInt(key)+length] = value;
}
results.length = arr.length + length;
}
}
})
// Slicing the object
Mscript.fn.extend({
eq: function(i) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack(( j >= 0 && j < len ? [ this[ j ] ] : [] ));
},
get: function( num ) {
if ( num == null ) {
return Array.slice.call( this );
}
return num < 0 ? this[ num + this.length ] : this[ num ];
},
first: function() {
return this.eq(0)
},
last: function() {
return this.eq(-1)
},
pushStack: function(arr) {
return Mscript(arr)
},
slice: function() {
return this.pushStack( slice.apply( this, arguments ) );
}
})
// HTML elemants manuplation
Mscript.fn.extend({
children: function() {
if (!this.length) return
elem = this[0];
return this.pushStack(Array(...(elem.children)));
},
removeClass: function(className) {
this.forEach(e => e.classList.remove(className));
return this;
},
addClass: function(className) {
this.forEach(e => e.classList.add(className));
return this;
},
toggle: function(className, state) {
if (state == undefined) {
this.forEach(e => e.classList.toggle(className));
} else if (typeof (state) == "boolean") {
this.forEach(e => e.classList.toggle(className, state));
} else {
this.forEach(e => e.classList.toggle(className));
}
return this;
},
getStyles: function(elem) {
elem = elem? elem: this[0];
var view = elem.ownerDocument.defaultView;
if ( !view || !view.opener ) {
view = window;
}
return view.getComputedStyle(elem);
},
css: function(property, value) {
if (value == undefined) {
return this.getStyles(this[0])[property];
} else {
const camelProp = property.replace(/(-[a-z])/, g => {
return g.replace("-", "").toUpperCase();
})
this.forEach(e => (e.style[camelProp] = value));
}
return this;
},
rcss: function(property) {
this.forEach(e => (e.style.removeProperty(property)));
return this;
},
show: function() {
return this.rcss("display");
},
hide: function(timeout=0) {
return this.css("display", "none");
},
val: function(value) {
if (!this.length) return '';
let elem = this[0];
if (value === undefined){
let mselect = [];
if (!elem.name || elem.disabled || ['file', 'reset', 'submit', 'button'].indexOf(elem.type) > -1) return;
if (elem.type === 'select-multiple') {
Array.prototype.slice.call(elem.options).forEach(function (option) {
if (!option.selected) return;
mselect.push(option.value);
});
return mselect;
}
if (mselect.length) {
return mselect;
}
if (['checkbox', 'radio'].indexOf(elem.type) > -1 && !elem.checked) {
return "off";
}else {
return "on";
}
return elem.value;
} else {
if (!elem.name || elem.disabled || ['file', 'reset', 'submit', 'button'].indexOf(elem.type) > -1) return;
if (elem.type === 'select-multiple') {
return Array.prototype.slice.call(elem.options).forEach(function (option) {
if (value.includes(option.value)) {
option.selected = true;
}
});
}
if (['checkbox'].indexOf(elem.type) > -1) {
if (value === "off") return elem.checked = false;
if (value === "on") return elem.checked = true;
}
if (['radio'].indexOf(elem.type) > -1) {
return this.each(this, function() {
if (this.value == value) this.checked = true;
})
}
return elem.value = value;
}
},
text: function(txt) {
if (txt === undefined) {
if (this.length) {
return this[0].innerText;
}
return null;
}
this.each(function() {this.innerText = txt});
},
html: function(txt) {
if (txt === undefined) {
if (this.length) {
return this[0].innerHTML;
}
return null;
}
this.each(function() {this.innerHTML = txt});
},
})
// Filtering
Mscript.fn.extend({
find: function(selector) {
let arr = [];
if (typeof selector !== "string") {
return false;
}
this.forEach(e => {
arr.push(...(e.querySelectorAll(selector)));
})
return this.pushStack(arr);
},
each: function(obj,cb) {
if (isFunction(obj)){cb=obj;obj=this;}
var length, i = 0;
if (isArrayLike( obj )) {
length = obj.length;
for ( ; i < length; i++ ) {
if ( cb.call( obj[ i ], i, obj[ i ] ) === false ) {
break;
}
}
} else {
for ( i in obj ) {
if ( cb.call( obj[ i ], i, obj[ i ] ) === false ) {
break;
}
}
}
return obj;
},
})
// Make all possible events
Mscript.fn.each(
( "blur focus focusin focusout resize scroll click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup contextmenu" ).split( " " ),
function( _i, name ) {
// Handle event binding
Mscript.fn[ name ] = function(fn) {
this.on( name, fn )
};
}
);
// Manage forms
Mscript.fn.extend({
serializeArray: function () {
var arr = [];
this.forEach(e => {
Array.prototype.slice.call(e.elements).forEach(function (field) {
if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return false;
if (field.type === 'select-multiple') {
Array.prototype.slice.call(field.options).forEach(function (option) {
if (!option.selected) return;
arr.push({
name: field.name,
value: option.value
});
});
return;
}
if (["radio", "checkbox"].indexOf(field.type) > -1 && !field.checked) return false;
arr.push({
name: field.name,
value: field.value
});
});
})
return arr;
},
formData: function () {
var o = {};
var a = this.serializeArray();
this.each(a, function () {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
},
autoFill: function(map, fillby) {
fillby = fillby || "name"
for (const [key, value] of Object.entries(map)) {
this.find(`[${fillby}="${key}"]`).val(value)
}
}
})
window.$ = window.Mscript = Mscript;
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment