Исправляем проблему с history.replaceState() в Chrome

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для модификации URL-адреса в браузере и соответствующего состояния без необходимости перезагружать страницу и создавать новую запись в истории браузера, воспользуйтесь методом history.replaceState(). Этот метод отлично подходит для AJAX-навигации в single-page приложениях.

Логика работы:

JS
Скопировать код
// URL изменяется на "updated-page.html", но страница при этом не перезагружается
history.replaceState({ detail: 'update' }, '', 'updated-page.html');

Суть: URL-адрес обновляется до updated-page.html, весь контент страницы остаётся без изменений. Объект состояния ({ detail: 'update' }) используется для отслеживания изменений в рамках текущей веб-страницы.

Важно помнить, что history.replaceState() не влияет на заголовок документа. Для его изменения необходимо отдельно прописать значение document.title:

Пример обновления заголовка:

JS
Скопировать код
// Теперь переименуем заголовок
document.title = 'Обновленный заголовок страницы';
history.replaceState({ detail: 'update' }, 'Обновленный заголовок страницы', 'updated-page.html');
Кинга Идем в IT: пошаговый план для смены профессии

Навигация по браузерному ландшафту

Каждый браузер имеет свои специфические характеристики, и они не всегда корректно обрабатывают параметр title для replaceState() и pushState(). В лучшем понимании этих тонкостей понадобится кое-какое время.

Выживание среди браузерных различий

Протестируйте свой код во всех популярных браузерах до релиза проекта, чтобы предотвратить неприятные сюрпризы. Имейте в виду, что поведение replaceState() может различаться в разных браузерах, например, Chrome или Opera.

Изменение заголовка документа

Когда осуществляется изменение заголовка документа, делаем это таким образом:

JS
Скопировать код
// Тсс, нас тут нет
document.getElementsByTagName('title')[0].innerHTML = 'новый заголовок';

Отслеживание изменений в навигации

Используйте событие window.onpopstate, чтобы отследить изменения в навигации истории браузера:

JS
Скопировать код
// О, кто-то нажал кнопку "назад"?
window.onpopstate = function(event) {
  if (event.state) {
    updateContent(event.state.detail);
  }
};

function updateContent(detail) {
  // Здесь размещаем логику для обновления контента
}

Обход препятствий AJAX

replaceState() в сочетании с AJAX позволяет получать и показывать новый контент, не вовлекая пользователя в ожидание перезагрузки страницы.

JS
Скопировать код
// Это время удивить пользователя новым контентом
function loadContent(url) {
  // Получаем контент, а затем обновляем URL без перезагрузки страницы
  fetch(url)
    .then(response => response.text())
    .then(html => {
      document.getElementById('content').innerHTML = html;
      history.replaceState({ content: html }, '', url);
    });
}

Если вы используете jQuery, это облегчает управление AJAX-контентом и взаимодействие с pushState и popstate.

Визуализация

Представьте history.replaceState() как хитроумного ассистента 🕵️‍♂️, который сценарий книги меняет так, не вызывая подозрений:

До использования ReplaceState: 📖 [Страница 1 – Вступление, Страница 2 – Развитие сюжета, Страница 3 – Кульминация]

Возвращается наш смекалистый помощник:

JS
Скопировать код
history.replaceState({page: 2}, "Заголовок", "/page-2");

После применения ReplaceState: 📖 [Страница 1 – Вступление, Страница 2 – Впечатляющий поворот сюжета!, Страница 3 – Кульминация]

Прочие даже не заподозрят, что что-то изменилось, история продолжает течь своим чередом.

Полезные материалы

  1. Метод History: replaceState() – Web API | MDN — подробное описание метода replaceState().
  2. Использование HTML5 History API | CSS-Tricks — руководство по работе с HTML5 History API.
  3. GitHub – devote/HTML5-History-API — повышение совместимости History API в браузерах, которые его не поддерживают изначально.
  4. javascript – Как изменить URL без перезагрузки страницы? – Stack Overflow — обсуждения на Stack Overflow по вопросу изменения URL без перезагрузки страницы.
  5. Якоря заголовков Markdown на GitHub · GitHub — использование history.replaceState() на практике.