Простой роутер на JavaScript
В одностраничных приложениях (Single Page Application,SPA) центральным компонентом является роутер (Router). Его задачей является определить какой обработчик нужно вызвать для данного маршрута. И сейчас я покажу Вам базовый принцип реализации роутера на JavaScript.
Код html страницы:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JS Router</title>
</head>
<body>
<div id="links">
<a href="/">Gallery</a>
<a href="/article/234019/kiazim">Article #234019</a>
<a href="/company/cartofan/post/2312">Cartofan Blog</a>
</div>
<script src="src/router.js"></script>
<script>
// инициализируем роутер
Router.init();
// запускаем главную страницу
Router.dispatch('/');
// обработчик нажатий на ссылки
let handler = event => {
// получаем запрошенный url
let url = new URL(event.currentTarget.href);
// запускаем роутер, предавая ему path
Router.dispatch(url.pathname);
// запрещаем дальнейший переход по ссылке
event.preventDefault();
}
// получаем все ссылки на странице
let anchors = document.querySelectorAll('a');
// вешаем на событие onclick обработчик
for( let anchor of anchors ) anchor.onclick = handler;
</script>
</body>
</html>
Сам скрипт Router.js
// `класс` роутера
let Router = {
// маршруты и соответствующие им обработчики
routes: {
"/": "index",
"/article/:id/:author": "article",
"/company/:name/post/:id": "company_blog",
},
// метод проходиться по массиву routes и создает
// создает объект на каждый маршрут
init: function() {
// объявляем свойство _routes
this._routes = [];
for( let route in this.routes ) {
// имя метода-обрботчика
let method = this.routes[route];
// добавляем в массив роутов объект
this._routes.push({
// регулярное выражение с которым будет сопоставляться ссылка
// ее надо преобразовать из формата :tag в RegEx
// модификатор g обязателен
pattern: new RegExp('^' + route.replace(/:\w+/g,'(\\w+)') + '$'),
// метод-обработчик
// определяется в объекте Route
// для удобства
callback: this[method]
});
}
},
dispatch: function(path) {
// количество маршрутов в массиве
var i = this._routes.length;
// цикл до конца
while( i-- ) {
// если запрошенный путь соответствует какому-либо
// маршруту, смотрим есть ли маршруты
var args = path.match(this._routes[i].pattern);
// если есть аргументы
if( args ) {
// вызываем обработчик из объекта, передавая ему аргументы
// args.slice(1) отрезает всю найденную строку
this._routes[i].callback.apply(this,args.slice(1))
}
}
},
// обработчик
// главной страницы
index: function() {
console.log("Main page");
},
// контроллер статей
article: function(id,author) {
console.log(`Article #${id} Author: ${author}`);
},
// контроллер блога компаний
company_blog: function(name,id) {
console.log(`Artwork #${name}, comment #${id}`)
}
}
Вот так можно создать простой роутер на JavaScript.
-
- Михаил Русаков
Комментарии (1):
Я новичк в js, но! Почему, зачем так закручивать роутер, почему нельзя сделать его проще, типа так: let page = router.run(); Router { run() { if(window.location.pathname === "/") { return this.page = new Index(); } if(window.location.pathname === "some-page") { return this.page = new SomePage(); } } } В чем ошибка такого кода? Чем такой код плохо? Хотелось бы услышать комментарий гуру кода (из всех ЯП)!!!
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.