Как написать маршрутизатор на VanillaJS

Запрос выглядит следующим образом:

  1. Реагировать на нажатие ссылки, показывая на странице содержимое, соответствующее маршруту.
  2. Когда пользователь нажимает на кнопку браузера назад или вперед, должен загружаться нужный маршрут и его содержимое.
  3. Если пользователь обновляет страницу, должно загружаться содержимое текущего маршрута.

Для начала сделайте HTML-страницу, которая будет выглядеть следующим образом:

<body>
    <div id="nav"></div>
    <div id="app"></div>

    <script src="src/index.js"></script>
</body>
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь в нашем index.js добавим следующий конфиг:

const routes = {
  '/': {
    linkLabel: 'Home',
    content: `I am in home page`
  },
  '/about': {
    linkLabel: 'About',
    content: `I am in about page`
  },
  '/friends': {
    linkLabel: 'Friends',
    content: `I am in friends page`,
  },
};
Войти в полноэкранный режим Выйти из полноэкранного режима

На этом этапе становится ясно, что мы пытаемся создать маршрутизатор с конфигурацией. Это означает, что нам нужно будет создать элементы навигации, а затем зарегистрировать обработчики нажатий.

Давайте добавим для них функции.

const app = document.querySelector('#app');
const nav = document.querySelector('#nav');

// function to create new nav items
const renderNavlinks = () => {
  const navFragment = document.createDocumentFragment();
  Object.keys(routes).forEach(route => {
    const { linkLabel } = routes[route];

    const linkElement = document.createElement('a')
    linkElement.href = route;
    linkElement.textContent = linkLabel;
    linkElement.className = 'nav-link';
    navFragment.appendChild(linkElement);
  });

  nav.append(navFragment);
};

// function to register click handlers
const registerNavLinks = () => {
  nav.addEventListener('click', (e) => {
    e.preventDefault();
    const { href } = e.target;
    history.pushState({}, "", href);
    navigate(e); // pending implementation
  });
};
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь нам нужно реализовать функцию navigate. Она будет обрабатывать фактическую навигацию.

const renderContent = route => app.innerHTML = routes[route].content;

const navigate = e => {
    const route = e.target.pathname;
    // this is responsible for adding the new path name to the history stack
    history.pushState({}, "", route);
    renderContent(route);
};
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь нам осталось только обработать событие pop state (обработка возврата браузера назад и вперед) и обработать начальную загрузку страницы.

const registerBrowserBackAndForth = () => {
  window.onpopstate = function (e) {
    const route = location.pathname;
    renderContent(route);
  };
};

const renderInitialPage = () => {
  const route = location.pathname;
  renderContent(route);
};
Вход в полноэкранный режим Выход из полноэкранного режима

Собираем все вместе:

(function bootup() {
  renderNavlinks();
  registerNavLinks();
  registerBrowserBackAndForth();
  renderInitialPage();
})();
Вход в полноэкранный режим Выход из полноэкранного режима

Финальная демонстрация:
Вот что мы пытаемся создать: (проверьте демонстрацию codesandbox)

Спасибо, что дочитали до конца.

Оцените статью
devanswers.ru
Добавить комментарий