Skip to content

Instantly share code, notes, and snippets.

@mauroreisvieira
Last active November 10, 2024 17:59
Show Gist options
  • Save mauroreisvieira/bab815d8856acbd2e911c4487364cdf7 to your computer and use it in GitHub Desktop.
Save mauroreisvieira/bab815d8856acbd2e911c4487364cdf7 to your computer and use it in GitHub Desktop.
Some basic utilities to help with your Typescript projects
export class Util {
private observer: MutationObserver;
constructor() {
/** CODE */
}
/**
* Save items in browser storage.
* @param {string} name
* @param {string} value
* @return {void}
*/
public static setStorage(name : string, value : any): void {
localStorage.setItem(name, value);
}
/**
* Get Item in storage.
* @param {string} name
* @return {string}
*/
public static getStorage(name : string): string {
return localStorage.getItem(name);
}
/**
* Remove Item in storage.
* @param {string} name
* @return {void}
*/
public static removeStorage(name: string): void {
localStorage.removeItem(name);
}
/**
* Save items in browser cookies.
* @param {string} name
* @param {any} value
* @param {void} days
* @return {void}
*/
public static setCookie(name: string, value: any, days: number): void {
const _d = new Date();
_d.setTime(_d.getTime() + 24 * 60 * 60 * 1000 * days);
document.cookie = name + '=" + value + ";path=/;expires=' + _d.toUTCString();
}
/**
* Get cookie.
* @param {string} name
* @return {string}
*/
public static getCookie(name: string): any {
const _v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return _v ? _v[2] : undefined;
}
/**
* Remove Item in cookie.
* @param {string} name
* @return {void}
*/
public static removeCookie(name: string): void {
this.setCookie(name, '', -1);
}
/**
* Receive array and field used to orde this array.
* @param {any} array
* @param {string} field
* @return {number}
*/
public static compare(array : any, field : string) : number {
return array.sort((a : any, b : any) => a.field !== b.field ? a.field < b.field ? -1 : 1 : 0);
}
/**
* Method to redirect to other url.
* @param {string} url
* @return {void}
*/
public static redirect(url : string) : void {
window.location.href = url;
}
/**
* Check if browser is connected to internet.
* @return {boolean}
*/
public static getOnlineState(): boolean {
return navigator.onLine;
}
/**
* The MutationObserver API lets you listen to changes made to a DOM node and react to it.
* When we create an instance of MutationObserver we specify a callback that gets details of changes made to the parent.
* If those changes include the removal of our target element then we can call dispose.
* @param {HTMLElement} targetElement [description]
* @param {any} callback [description]
* @param {any} config [description]
* @return {void}
*/
public mutationObserver(targetElement: HTMLElement, callback: any, opts: any): void {
const defaultConfig = {
attributes: true, /** set to true if mutations to target's attributes are to be observed. */
childList: true, /** set to true if additions and removals of the target node's child elements are to be observed. **/
characterData: false, /** set to true if mutations to target's data are to be observed. */
subtree: false /** set to true if mutations to not just target, but also target's descendants are to be observed. */
};
const opts = {..defaultConfig, ...opts};
/** create some resources that need to be cleaned up */
this.observer = new MutationObserver((mutationsList) => {
callback(mutationsList);
});
// Start observing the target node for configured mutations
this.observer.observe(targetElement, opts);
}
/**
* Finally, we need to make sure that the observer itself doesn’t cause a memory leak!
* The observer is connected to the parentElement which (we assume) will still be hanging around,
* so we need to make sure that we disconnect it as part of disposal.
* @return {void}
*/
public disposeObserver(): void {
/** clean up my resources & clean up my observer */
this.observer.disconnect();
delete this.observer;
}
/**
* Media queries are useful when you want to apply CSS styles depending on a device's general type.
* @param {number} minWidth
* @param {number} maxWidth
* @return {boolean}
*/
public mediaQuery(minWidth: number, maxWidth: number): boolean {
let media;
if (minWidth && maxWidth) {
media = window.matchMedia('(min-width: ' + minWidth + 'px) and (max-width:' + maxWidth + 'px)').matches;
} else if (minWidth) {
media = window.matchMedia('min-width:' + minWidth + 'px').matches;
} else {
media = window.matchMedia('max-width:' + maxWidth + 'px').matches;
}
return media;
}
/**
* The Window.navigator read-only property returns a reference to the Navigator object,
* which can be queried for information about the application running the script.
* @return {string} browser
*/
public static detectBrowser(): string {
const agent = navigator.userAgent;
let browser;
if (agent.indexOf('Chrome') > -1) {
browser = 'Chrome';
} else if (agent.indexOf('Safari') > -1) {
browser = 'Safari';
} else if (agent.indexOf('Opera') > -1) {
browser = 'Opera';
} else if (agent.indexOf('Firefox') > -1) {
browser = 'Firefox';
} else if (agent.indexOf('MSIE') > -1) {
browser = 'IE';
}
return browser;
}
/**
* Change CSS elements usign JavaScript.
* @param {HTMLElement} element
* @param {any} props
*/
public static changeProperty(element: HTMLElement, props: any): void {
if (Util.detectBrowser() === 'IE') {
Object.keys(props).forEach((key: any) => {
const property = key.split('-');
const propertyName = property[property.length - 1];
element.style[propertyName] = props[key];
});
} else {
Object.keys(props).forEach((key: any) => {
element.style.setProperty(key, props[key]);
});
}
}
/**
* Extend a JavaScript object with the key/value pairs of another.
* @param {any} obj
* @param {any} src
* @return {any}
*/
public static extend(obj: any, src: any): any {
for (var key in src) {
if (src.hasOwnProperty(key)) {
obj[key] = src[key];
}
}
return obj;
}
/**
* function when you want it to execute only once after a defined interval of time.
* If the event occurs multiple times within the interval, the interval is reset each time.
*
* @param {Function} callback takes the function that should be called
* @param {number} delay number of times that function should be called within the time limit
* @return {Function}
*/
public static debounce(callback: Function, delay: number = 250): Function {
let inDebounce: number;
if (typeof callback !==
'function') {
throw new TypeError('Expected a function');
}
return (...args: any[]) => {
if (inDebounce) {
clearTimeout(inDebounce);
}
inDebounce = window.setTimeout(() => {
callback(...args);
inDebounce = undefined;
}, delay);
};
}
/**
* Throttle a function when you want it to execute periodically with an interval in between each execution.
*
* @param {Function} callback takes the function that should be called
* @param {number} delay number of times that function should be called within the time limit
* @return {Function}
*/
public static throttle (callback: Function, delay: number = 250): Function {
let lastCall: number = 0;
if (typeof callback !== 'function') {
throw new TypeError('Expected a function');
}
return (...args: any[]) => {
const now = new Date().getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return callback(...args);
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment