Skip to content

Instantly share code, notes, and snippets.

@iliakan
Created October 29, 2019 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iliakan/13ea84b71aed24b786c844a4228822b2 to your computer and use it in GitHub Desktop.
Save iliakan/13ea84b71aed24b786c844a4228822b2 to your computer and use it in GitHub Desktop.
import renderPage from 'utils/renderPage';
export default new class Router {
constructor() {
this.routes = [];
document.addEventListener('click', (event) => {
const link = event.target.closest('a');
if (!link) return;
const href = link.getAttribute('href');
if (href && href.startsWith('/')) {
event.preventDefault();
this.navigate(href);
}
});
}
route() {
const activeRoute = decodeURI(window.location.pathname)
.replace(/^\/|\/$/, '')
.replace(/\?.*$/, '');
if (this.currentRoute === activeRoute) return;
this.currentRoute = activeRoute;
const newRoute = this.routes
.find(({route}) => typeof route === 'string' ? activeRoute === route : activeRoute.match(route));
if (newRoute) {
renderPage(newRoute.page, this.currentRoute);
} else if (this.notFoundPage) {
renderPage(this.notFoundPage, this.currentRoute);
}
}
navigate(path) {
history.pushState(null, null, path);
this.route();
}
addRoute(route, page) {
this.routes.push({route, page});
return this;
}
notFoundHandler() {
renderPage(this.notFoundPage);
}
setNotFoundPage(page) {
this.notFoundPage = page;
return this;
}
listen() {
window.addEventListener('popstate', () => this.route());
this.route();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment