Управление фокусом

Navigo — это лёгкая и гибкая библиотека для маршрутизации в браузере на стороне клиента. Она позволяет управлять переходами между «страницами» без перезагрузки, поддерживает динамические параметры, вложенные маршруты и обработку несуществующих маршрутов. Основной принцип работы Navigo строится вокруг определения маршрутов и привязки к ним обработчиков.

Создание экземпляра роутера выполняется следующим образом:

import Navigo from 'navigo';

const router = new Navigo('/', { hash: true });

Параметры конструктора:

  • root — базовый путь приложения. Обычно '/'.
  • useHash — логическое значение: использовать ли hash-based маршрутизацию (true) или HTML5 History API (false).
  • hash — имя хэша, если используется hash-маршрутизация, по умолчанию '#!'.

Определение маршрутов

Маршруты задаются методом on, который принимает путь и обработчик:

router.on('/home', () => {
    console.log('Маршрут /home активирован');
});

Путь может содержать динамические сегменты:

router.on('/user/:id', (params) => {
    console.log(`Пользователь с ID: ${params.id}`);
});

Здесь :id — параметр, который извлекается автоматически и передаётся в объект params.

Обработка нескольких маршрутов

Метод on поддерживает передачу объекта для групповой регистрации:

router.on({
    '/about': () => console.log('О странице About'),
    '/contact': () => console.log('Контакты')
});

Также возможно использовать регулярные выражения:

router.on(/\/product\/(\d+)/, (params) => {
    console.log(`Продукт: ${params[0]}`);
});

Управление переходами

Для программного перехода между маршрутами используется метод navigate:

router.navigate('/home');

Можно добавлять опции, например, чтобы не создавать запись в истории:

router.navigate('/home', { updateBrowserURL: false });

Вложенные маршруты

Navigo поддерживает вложенные маршруты через объектную структуру:

router.on({
    '/dashboard': {
        '/stats': () => console.log('Статистика'),
        '/settings': () => console.log('Настройки')
    }
});

При переходе на /dashboard/stats будет вызван соответствующий обработчик.

Обработка несуществующих маршрутов

Для маршрутов, не соответствующих определённым путям, используется notFound:

router.notFound(() => {
    console.log('Маршрут не найден');
});

Это полезно для реализации страницы 404 без перезагрузки.

Хуки и события

Navigo предоставляет несколько хуков для управления состоянием роутера:

  • before — вызывается перед обработкой маршрута, позволяет отменить переход:
router.hooks({
    before: (done, params) => {
        if (!params.id) {
            console.log('ID отсутствует, переход отменён');
            done(false);
        } else {
            done();
        }
    }
});
  • after — вызывается после завершения маршрута, например для логирования или управления фокусом элементов на странице:
router.hooks({
    after: (params) => {
        const mainContent = document.querySelector('#main');
        if (mainContent) mainContent.focus();
    }
});

Использование after особенно важно для управления фокусом после изменения контента, чтобы обеспечить доступность и корректное взаимодействие с клавиатурой и скринридерами.

Управление фокусом после маршрутизации

После перехода на новый маршрут часто необходимо перемещать фокус на ключевой элемент страницы — заголовок, форму или основной контейнер. Это повышает удобство навигации и соответствует стандартам доступности.

Пример установки фокуса на основной контейнер:

router.hooks({
    after: () => {
        const container = document.querySelector('#main-content');
        if (container) {
            container.setAttribute('tabindex', '-1');
            container.focus();
        }
    }
});

Важные моменты:

  • Добавление tabindex="-1" позволяет программно фокусировать элемент, который обычно не является фокусируемым.
  • Фокус нужно устанавливать после того, как контент полностью обновился.
  • Если страница содержит динамически загружаемые компоненты, фокусировку лучше выполнять с небольшой задержкой или после события DOMContentLoaded соответствующего блока.

Навигация с сохранением состояния

Методы Navigo позволяют сохранять состояние между переходами, например, при использовании фильтров или прокрутки. Это делается через объект состояния в navigate:

router.navigate('/search', { state: { query: 'javascript' } });

Доступ к состоянию выполняется через router.lastRouteResolved():

const state = router.lastRouteResolved().data.state;
console.log(state.query); // 'javascript'

Такой подход помогает корректно восстанавливать фокус и положение элементов на странице при возврате к предыдущему маршруту.

Динамическое изменение маршрутов

Маршруты можно добавлять и удалять во время работы приложения:

router.on('/profile', () => console.log('Профиль'));
router.off('/profile'); // удаляет обработчик

Это полезно для условной загрузки функционала и управления доступом пользователей.

Резюме ключевых методов

  • new Navigo(root, options) — создание роутера.
  • on(path, handler) — регистрация маршрута.
  • navigate(path, options) — программный переход.
  • notFound(handler) — обработка неизвестных маршрутов.
  • hooks({ before, after }) — хуки для управления переходами.
  • off(path) — удаление маршрута.
  • lastRouteResolved() — информация о последнем активном маршруте.

Эти инструменты в совокупности позволяют строить современные SPA с управлением фокусом, поддержкой доступности и динамическим контентом.