При разработке SPA (Single Page Application) с использованием Navigo навигация происходит без полной перезагрузки страницы, что создаёт потенциальные проблемы для пользователей с ограниченными возможностями, особенно для тех, кто использует экранные читалки. Screen reader опирается на изменения в DOM и уведомления о фокусе, поэтому важно правильно обновлять состояние страницы при смене маршрутов.
Основная задача — обеспечить, чтобы при переходе по маршрутам:
import Navigo from 'navigo';
const router = new Navigo('/', { hash: true });
router
.on('/', () => loadPage('home'))
.on('/about', () => loadPage('about'))
.on('/contact', () => loadPage('contact'))
.resolve();
Ключевой момент: после каждого вызова
loadPage необходимо обновлять фокус и
уведомлять screen reader о смене контента.
Для правильной поддержки screen reader важно установить фокус на
основной контейнер нового контента. Обычно используют элемент
<main> или отдельный div с атрибутом
role="main":
function loadPage(page) {
const main = document.querySelector('main');
// Очистка текущего содержимого
main.innerHTML = '';
// Подгрузка нового контента
fetch(`/pages/${page}.html`)
.then(response => response.text())
.then(html => {
main.innerHTML = html;
// Обновление атрибута для screen reader
main.setAttribute('tabindex', '-1');
main.focus();
});
}
Объяснение:
tabindex="-1" позволяет программно устанавливать фокус
на элемент, который обычно не доступен через табуляцию.main.focus() уведомляет screen reader о появлении
нового содержимого.Для SPA особенно важны ARIA-live регионы, чтобы screen reader автоматически озвучивал обновления:
<div id="aria-notifier" aria-live="polite" style="position:absolute;left:-9999px;"></div>
function announce(message) {
const notifier = document.getElementById('aria-notifier');
notifier.textContent = '';
setTimeout(() => {
notifier.textContent = message;
}, 100);
}
function loadPage(page) {
const main = document.querySelector('main');
fetch(`/pages/${page}.html`)
.then(response => response.text())
.then(html => {
main.innerHTML = html;
main.setAttribute('tabindex', '-1');
main.focus();
announce(`Загружена страница: ${page}`);
});
}
Принцип работы: Screen reader отслеживает изменения
в элементе с aria-live="polite" и озвучивает новые
сообщения. Это обеспечивает информирование пользователя о смене контента
без необходимости полной перезагрузки страницы.
Если на странице присутствуют модальные окна, дропдауны или динамические списки, необходимо корректно управлять фокусом и атрибутами ARIA:
function openModal(modalId) {
const modal = document.getElementById(modalId);
modal.style.display = 'block';
modal.setAttribute('aria-hidden', 'false');
// Перемещение фокуса на заголовок модального окна
const heading = modal.querySelector('h2');
heading.setAttribute('tabindex', '-1');
heading.focus();
}
function closeModal(modalId) {
const modal = document.getElementById(modalId);
modal.style.display = 'none';
modal.setAttribute('aria-hidden', 'true');
// Возврат фокуса к кнопке открытия
const trigger = document.querySelector(`[data-target="${modalId}"]`);
trigger.focus();
}
Важно: screen reader читает элементы с
aria-hidden="false" и игнорирует скрытые элементы.
Установка фокуса на заголовок модального окна позволяет пользователю
сразу понять контекст.
Для полной доступности необходимо гарантировать, что все маршруты и интерактивные элементы доступны через Tab/Shift+Tab, а динамический контент не теряется при перемещении фокуса. Для этого используют:
tabindex="0" для элементов, которые должны быть
доступными для табуляции.document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
const modal = document.querySelector('.modal[aria-hidden="false"]');
if (modal) closeModal(modal.id);
}
});
Хотя основное предназначение Navigo — клиентская маршрутизация, важно поддерживать:
router.navigate('/about')) для корректной
истории браузера.document.title и
meta description для SEO и screen reader:router.on('/about', () => {
document.title = 'О нас';
loadPage('about');
});
Вывод: изменение заголовка страницы помогает screen reader сообщать пользователю контекст текущей страницы, особенно при переключении между маршрутами.
<main>,
<header>, <nav> повышает
доступность.document.title и
ARIA-атрибутов — позволяет screen reader правильно
интерпретировать контент.Эти методы обеспечивают корректную работу Navigo в SPA с полной поддержкой screen reader, создавая инклюзивный пользовательский опыт для людей с ограничениями зрения.