@rajaniraiyn/raj.js
Version:
A modern, fast, performant and lightweight jQuery alternative.
537 lines (531 loc) • 19.2 kB
JavaScript
/**!
Raj.js
© 2021 Rajaniraiyn
A modern alternative to jQuery.
*/
((_) => {
/**
* to handle jQuery "Sizzle" selector https://github.com/jquery/sizzle
*/
function raj(selector = undefined) {
switch (selector) {
case undefined:
return;
default:
// @ts-ignore
selector = selector.trim();
function isSpecialSelector(selector) {
switch (selector.includes("#") &&
(selector.includes(".") || /[~!+:>\\\-()\[\]*]\w*/gm.test(selector))) {
case true:
return true;
default:
// used for some special selectors
return /[~!+:>\\\-()\[\]*]\w*/gm.test(selector);
}
//if (selector.includes("#") && selector.includes(".")) return true;
}
switch (isSpecialSelector(selector)) {
case true:
return new Raj(document.querySelectorAll(selector), selector);
default:
switch (selector.startsWith("#")) {
case true:
return new Raj(document.getElementById(selector.replace("#", "")), selector);
default:
switch (selector.startsWith(".")) {
case true:
return new Raj(document.getElementsByClassName(selector.replace(".", "")), selector);
default:
return new Raj(document.getElementsByTagName(selector), selector);
}
}
}
}
/*
if (selector === undefined) return;
// @ts-ignore
selector = selector.trim();
function isSpecialSelector(selector: string): boolean {
if (selector.includes("#") && selector.includes(".")) return true;
var specialChars = [
"~",
"!",
"+",
":",
">",
",",
"-",
"(",
")",
"[",
"]",
"*",
];
for (var i = 0, len = specialChars.length; i < len; i++) {
if (selector.includes(specialChars[i])) return true;
}
return false;
}
if (isSpecialSelector(selector)) {
return new Raj(document.querySelectorAll(selector), selector);
} else if (selector.startsWith("#")) {
return new Raj(
document.getElementById(selector.replace("#", "")),
selector
);
} else if (selector.startsWith(".")) {
return new Raj(
document.getElementsByClassName(selector.replace(".", "")),
selector
);
} else return new Raj(document.getElementsByTagName(selector), selector);
*/
}
raj["version"] = "1.0.0";
/**
* performance focused forEach loop
* using "reversed for loop"
*/
function forEach(array, callback) {
for (var i = 0, len = array.length; i < len; i++) {
callback(array[i], i);
}
}
class Raj extends Array {
selector;
constructor(elements = undefined, selector) {
switch (elements.length) {
case undefined:
elements = [elements];
break;
default:
elements = [...elements];
break;
}
//elements = elements.length === undefined ? [elements] : [...elements];
super(...elements);
this["context"] = window.document;
this.selector = selector;
return this;
}
/**
* hides the selected elements
*
*/
hide() {
forEach(this, (element) => {
element[raj.expando] = { display: element.style.display };
element.style.setProperty("display", "none");
});
return this;
}
/**
* makes hidden selected elements visible
*
*/
show() {
forEach(this, (element) => {
element.style.setProperty("display", element[raj.expando]["display"]);
});
return this;
}
eq(index) {
return new Raj(this[((index % this.length) + this.length) % this.length], this.selector);
}
/**
* selects first element among selected element
*
*/
first() {
return this.eq(0);
}
/**
* selects last element among selected element
*
*/
last() {
return this.eq(-1);
}
even() {
// @ts-ignore
return this.filter((_, i) => {
return i % 2 !== 0;
});
}
odd() {
// @ts-ignore
return this.filter((_, i) => {
return i % 2 === 0;
});
}
not(selector = undefined) {
var not = raj(selector);
// @ts-ignore
return this.filter((element) => {
return !not.includes(element);
});
}
/**
* Adds class name to all selected elements
*
*/
addClass(className) {
forEach(this, (element) => {
element.classList.add(className);
});
return this;
}
/**
* Removes a class if it presents in selected elements
*
*/
removeClass(className) {
forEach(this, (element) => {
element.classList.remove(className);
});
return this;
}
/**
* Toggles a class in all selected elements
*
*/
toggleClass(className) {
forEach(this, (element) => {
element.classList.toggle(className);
});
return this;
}
/**
* Adds a event listener to all selected elements
*
*/
on(event, callback, options) {
forEach(this, (element) => {
element.addEventListener(event, callback, options);
});
}
off(event, selector, handler) {
if (handler === undefined) {
forEach(this, (element) => {
// remove all events
});
}
}
click(handler, ...args) {
if (handler === undefined) {
forEach(this, (element) => {
element.click();
});
}
this.on("click", handler, ...args);
}
/**
* Adds a HTML string after all selected elements
*
*/
after(...args) {
var elementText = [...args].reverse().join("");
forEach(this, (element) => {
element.insertAdjacentHTML("afterend", elementText);
});
return this;
}
/**
* Adds HTML string within all selected elements as a last child
*
*/
append(...args) {
var elementText = [...args].join("");
forEach(this, (element) => {
element.insertAdjacentHTML("beforeend", elementText);
});
return this;
}
/**
* Adds HTML string within all selected elements as a first child
*
*/
prepend(...args) {
var elementText = [...args].reverse().join("");
forEach(this, (element) => {
element.insertAdjacentHTML("afterbegin", elementText);
});
return this;
}
/**
* Adds HTML string before all selected elements
*
*/
before(...args) {
var elementText = [...args].join("");
forEach(this, (element) => {
element.insertAdjacentHTML("beforebegin", elementText);
});
return this;
}
/**
* Handles the attributes of a DOM element i.e. first among the selected elements
*
* Acts as both getter and setter & can also take multiple attributes at once
* as a key value Object
*
*/
attr(attribute, value) {
switch (value) {
case undefined:
switch (typeof attribute) {
case "object":
var values = Object.values(attribute);
forEach(Object.keys(attribute), (key, i) => {
this[0].setAttribute(key, values[i]);
});
break;
default:
return this[0].getAttribute(attribute);
}
default:
switch (typeof value) {
case "function":
forEach(this, (element, i) => {
// @ts-ignore
value(i, element.getAttribute(attribute));
});
break;
default:
return this[0].setAttribute(attribute, value);
}
}
// if (value === undefined) {
// if (typeof attribute === "object") {
// var values: string[] = Object.values(attribute);
// forEach(Object.keys(attribute), (key: string, i: number) => {
// this[0].setAttribute(key, values[i]);
// });
// }
// return this[0].getAttribute(attribute);
// } else if (typeof value === "function") {
// forEach(this, (element: HTMLElement, i: number) => {
// // @ts-ignore
// value(i, element.getAttribute(attribute));
// });
// }
// return this[0].setAttribute(attribute, value);
}
/**
* Handles the styles of a DOM element i.e. first among the selected elements
*
* Acts as both getter and setter & can also take multiple attributes at once
* as a key value Object
*
*/
css(property, value) {
switch (value) {
case undefined:
switch (typeof property) {
case "object":
var values = Object.values(property);
forEach(Object.keys(property), (key, i) => {
this[0].style.setProperty(key, values[i]);
});
break;
default:
return getComputedStyle(this[0])[property];
}
default:
switch (typeof value) {
case "function":
forEach(this, (element, i) => {
// @ts-ignore
value(i, getComputedStyle(element)[property]);
});
break;
default:
return this[0].style.setProperty(property, value);
}
}
// if (value === undefined) {
// if (typeof property === "object") {
// var values: string[] = Object.values(property);
// forEach(Object.keys(property), (key: string, i: number) => {
// this[0].style.setProperty(key, values[i]);
// });
// }
// //@ts-ignore
// return getComputedStyle(this[0])[property];
// } else if (typeof value === "function") {
// forEach(this, (element: HTMLElement, i: number) => {
// // @ts-ignore
// value(i, getComputedStyle(element)[property]);
// });
// }
// return this[0].style.setProperty(property, value);
}
/**
* Cleans everything inside all selected elements i.e. excluding the element itself
*
*/
empty() {
forEach(this, (element, i) => {
element.innerHTML = null;
});
return this;
}
/**
* Checks wether a class is present in the first element of selected
*
*/
hasClass(className) {
return this[0].classList.contains(className);
}
/**
* Returns the height of the first element of selected
*
*/
height() {
return parseFloat(getComputedStyle(this[0])["height"]);
}
outerHeight(includeMargin) {
if (includeMargin) {
return (this.height() +
parseInt(this.css("margin-top")) +
parseInt(this.css("margin-bottom")));
}
return this[0].offsetHeight;
}
/**
* Returns the width of the first element of selected
*
*/
width() {
return parseFloat(getComputedStyle(this[0])["width"]);
}
outerWidth(includeMargin) {
if (includeMargin) {
return (this.width() +
parseInt(this.css("margin-left")) +
parseInt(this.css("margin-right")));
}
return this[0].offsetWidth;
}
/**
* Stores some data for the first element of selected
*
*/
data(name, value) {
return raj.data(this[0], name, value);
}
each(callback) {
raj.each(this, callback);
}
}
raj.expando = "raj" + Date.now();
document[raj.expando] = {};
raj.extend = (target, ...args) => {
switch ([...args][0]) {
case undefined:
return Object.assign(raj, target);
default:
return Object.assign(target, ...args);
}
// if ([...args][0] === undefined) {
// return Object.assign(raj, target);
// }
// return Object.assign(target, ...args);
};
raj.noConflict = (removeAll) => {
switch (removeAll) {
case true:
window["$"] = window["jQuery"] = window["raj"] = undefined;
break;
case false:
window["$"] = undefined;
}
//if (removeAll) window["raj"] = window["jQuery"] = window["$"] = undefined;
//else window["$"] = undefined;
return raj;
};
raj.data = (element, name, value) => {
switch (value) {
case undefined:
switch (raj.cache[element[raj.expando]]) {
case undefined:
raj.cache[element[raj.expando]] = {};
break;
}
switch (typeof name) {
case "string":
return raj.cache[element[raj.expando]][name];
case "object":
console.log(raj.cache[element[raj.expando]]);
element[raj.expando] = ++raj.cache.latest;
if (Object.keys(raj.cache[element[raj.expando]]).length === 0)
//@ts-ignore
return (raj.cache[element[raj.expando]] = name);
return Object.assign(raj.cache[element[raj.expando]], name);
}
break;
default:
element[raj.expando] = ++raj.cache.latest;
switch (raj.cache[element[raj.expando]]) {
case undefined:
raj.cache[element[raj.expando]] = {};
break;
}
return (raj.cache[element[raj.expando]][name] = value);
}
// if (value !== undefined) {
// element[raj.expando] = ++raj.cache.latest;
// if (raj.cache[element[raj.expando]] === undefined)
// raj.cache[element[raj.expando]] = {};
// return (raj.cache[element[raj.expando]][name] = value);
// }
// if (typeof name === "string") {
// if (raj.cache[element[raj.expando]] === undefined)
// raj.cache[element[raj.expando]] = {};
// return raj.cache[element[raj.expando]][name];
// } else if (typeof name === "object") {
// element[raj.expando] = ++raj.cache.latest;
// if (raj.cache[element[raj.expando]] === undefined)
// raj.cache[element[raj.expando]] = {};
// var values = Object.values(name);
// forEach(Object.keys(name), (key: string, i: number) => {
// raj.cache[element[raj.expando]][key] = values[i];
// });
// }
};
raj.removeData = (element, name) => {
switch (name) {
case undefined:
raj.cache[element[raj.expando]] = undefined;
break;
}
// if (name === undefined) {
// raj.cache[element[raj.expando]] = undefined;
// }
raj.cache[element[raj.expando]][name] = undefined;
};
raj.when = async (...deferreds) => {
// @ts-ignore
return Object.assign(...deferreds);
};
raj.cache = { latest: 0 };
raj.now = Date.now;
raj.parseJSON = JSON.parse;
raj.inArray = (item, array) => {
return array.indexOf(item);
};
raj.isArray = (arr) => {
return Array.isArray(arr);
};
raj.isFunction = (fun) => {
return typeof fun === "function";
};
raj.each = (array, callback) => {
forEach(array, (element, index) => {
callback(index, element);
});
};
window["raj"] = window["jQuery"] = window["$"] = raj;
})();
//# sourceMappingURL=raj.js.map