Есть ли какое-то событие, на которое я могу подписаться, когда изменяется состояние истории? Как?
Как определить, когда используются history.pushState и history.replaceState?
Ответ 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>
с указанным кодом, но это еще больше перехитрит.