nova-frontend
Version:
Nova is an alternative to all those gigantic front-end frameworks, that often do more than is necessary when it comes to building simple UIs. Pure Vanilla Javascript is performance-wise the best way to build your front-end in a SPA, but it can be hard to
102 lines (93 loc) • 2.56 kB
JavaScript
/**
* @name Router
* @class
* @desc
* To get the full SPA feel the router is here for rendering different groups or components based on the url.
*
* @example
* import { Router, Group, Element, Generator, root } from '../../';
*
* const wrapper = new Element('div', root, { id: 'wrapper' }, true);
*
* const generator = new Generator;
* const component = generator.createTree(`
* div
* h1 innerText: 'Router example.'
* button innerText: 'Click it'
* end`)
*
* component.retrieve('button')[0].addEventListener('click', () => {
* Router.changePath('/about');
* })
*
* const about = new Element('h1', root, { innerText: 'Hello there!'}).createComponent();
* const group = new Group([component], wrapper);
*
* new Router('/', [group])
* new Router('/about', [about]);
*
* @param {String} path - The path bound to this route. All components applied will be rendered only when the URI is the same.
* @param {Components[]} componentArray - Array of components. If you want to supply an element you can do Element.createComponent();
*/
module.exports = class Router {
#path
#componentArray
#rendered
constructor(path, componentArray) {
this.#path = path;
this.#componentArray = componentArray;
this.#rendered = false;
this.#checkPath();
}
get path() {
return this.#path
}
set path(newPath) {
this.#path = newPath;
}
#checkPath() {
this.#addChangeListener();
if (this.path === window.location.pathname) {
this.#render();
}
}
#render() {
this.#componentArray.forEach(comp => comp.render());
this.#rendered = true;
}
#unrender() {
this.#componentArray.forEach(comp => comp.unrender());
this.#rendered = false;
}
/**
* @desc
* Returns current url path
* @returns current path
*/
static getPath() {
return window.location.pathname;
}
/**
* @desc
* A static mathod that uses history.pushState to set new url location.
* @example
* Router.newPath('/contact');
* @param {String} newPath
*/
static changePath(newPath) {
window.history.pushState({}, '', newPath);
window.dispatchEvent(new Event('locationChange'));
}
#addChangeListener() {
['locationChange', 'popstate'].forEach(state => {
window.addEventListener(state, () => {
const url = window.location.pathname;
if (url === this.#path && !this.#rendered) {
this.#render();
} else if (this.#rendered) {
this.#unrender();
}
})
})
}
}