History API в браузерах позволяет управлять историей навигации без полной перезагрузки страницы. Основные методы включают:
history.pushState(state, title, url) — добавляет новый
элемент в историю браузера.history.replaceState(state, title, url) — заменяет
текущий элемент истории.window.onpopstate — событие, срабатывающее при
навигации назад или вперёд.Однако поддержка History API в старых браузерах (например, Internet Explorer 9 и ниже, старые версии Android Browser и Safari) ограничена. Эти ограничения проявляются в невозможности корректно использовать pushState, replaceState и обработку события popstate. В таких случаях возникают проблемы с корректной навигацией в одностраничных приложениях (SPA), где переход между “страницами” осуществляется динамически.
Полифиллы решают проблему отсутствия или неполной реализации History API в старых браузерах. Основные задачи полифилла:
pushState и
replaceState.popstate при изменении URL.#) как альтернативой History
API.Полифиллы не способны полностью воспроизвести поведение современного History API, но обеспечивают совместимость, позволяя SPA корректно работать в устаревших браузерах.
Page.js — это библиотека маршрутизации для SPA, которая использует
History API для навигации без перезагрузки страницы. В современных
браузерах Page.js использует pushState и событие
popstate для управления маршрутами.
В старых браузерах, где History API недоступен, Page.js может быть
сконфигурирован на работу через хеш-историю. При этом URL изменяется
через window.location.hash, а маршруты отслеживаются через
событие hashchange. Пример конфигурации:
page({
hashbang: true
});
Опция hashbang: true заставляет Page.js использовать
хеши вместо History API. Это обеспечивает совместимость с браузерами, не
поддерживающими pushState.
Один из распространённых подходов — создание условного полифилла, который проверяет поддержку History API и заменяет методы при необходимости:
if (!window.history.pushState) {
window.history.pushState = function(state, title, url) {
window.location.hash = url;
};
window.history.replaceState = function(state, title, url) {
var hashIndex = window.location.href.indexOf('#');
window.location.href = window.location.href.substring(0, hashIndex) + '#' + url;
};
window.onpopst ate = function(event) {
var hash = window.location.hash.replace('#', '');
// Логика маршрутизации через Page.js или аналог
page(hash);
};
}
В этом примере:
pushState заменяется на изменение хеша URL.replaceState корректирует текущий URL без добавления
нового элемента в историю.onpopstate вызывается при изменении хеша, имитируя
стандартное событие popstate.При использовании Page.js полифилл подключается перед инициализацией маршрутов:
// Подключение полифилла
// ...
// Настройка маршрутов
page('/', () => {
console.log('Главная страница');
});
page('/about', () => {
console.log('Страница о нас');
});
// Инициализация Page.js
page({ hashbang: !history.pushState });
Таким образом, Page.js автоматически выбирает подходящий механизм навигации: History API или хеши.
hashchange.Использование полифиллов совместно с Page.js обеспечивает максимальную совместимость SPA и позволяет старым браузерам корректно обрабатывать маршруты и навигацию без полной перезагрузки страницы.