Подтвердить что ты не робот

Как определить, когда используются history.pushState и history.replaceState?

Есть ли какое-то событие, на которое я могу подписаться, когда изменяется состояние истории? Как?

4b9b3361

Ответ 1

Событие onpopstate должно быть запущено при изменении истории, вы можете привязать его к вашему коду следующим образом:

window.onpopstate = function (event) {
  // do stuff here
}

Это событие также может быть запущено при загрузке страницы, вы можете определить, было ли событие запущено из загрузки страницы, или с помощью pushState/replaceState, проверив объект события для свойства состояния, он будет undefined if событие было вызвано загрузкой страницы

window.onpopstate = function (event) {
  if (event.state) {
    // history changed because of pushState/replaceState
  } else {
    // history changed because of a page load
  }
}

В настоящее время, к сожалению, нет события onpushstate, чтобы обойти это, вам нужно обернуть оба метода pushState и replaceState, чтобы реализовать собственное событие onpushstate.

У меня есть библиотека, которая упрощает работу с pushState, возможно, стоит проверить ее называться Davis.js, она предоставляет простой api для работы с маршрутизацией на основе pushState.

Ответ 2

Я использовал это, чтобы также получать уведомления о том, когда вызываются pushState и replaceState:

// Add this:
var _wr = function(type) {
    var orig = history[type];
    return function() {
        var rv = orig.apply(this, arguments);
        var e = new Event(type);
        e.arguments = arguments;
        window.dispatchEvent(e);
        return rv;
    };
};
history.pushState = _wr('pushState'), history.replaceState = _wr('replaceState');

// Use it like this:
window.addEventListener('replaceState', function(e) {
    console.warn('THEY DID IT AGAIN!');
});
Тем не менее, он обычно переполняется. И это может не работать во всех браузерах. (Меня интересует только моя версия моего браузера.)

NB. Он также не работает в сценариях содержимого расширенного содержимого Google Chrome, поскольку он не позволяет изменять среду JS сайта. Вы можете обойти это, вставив <script> с указанным кодом, но это еще больше перехитрит.