эффективно отфильтровывать состояния, добавленные history.pushState на моей собственной веб-странице
Мотивация:
У меня есть страница, которая сразу же превращается в счетчик при нажатии на ссылку. Когда браузер получает щелчок кнопки «Назад», находясь в этом «раскручиваемом» состоянии, я бы хотел, чтобы он делал то, что имеет в виду пользователь, и просто снова начинал показывать текущую страницу (без вращения) при нажатии. Я хочу использовать history.pushState для достижения этой цели.
Проблема:
Кажется, нет никакого способа снова надежно отфильтровать «спиннеризированное» состояние из истории.
Я могу использовать некоторое состояние страницы и history.back() или history.forward() из обработчика pageshow, чтобы пропустить элемент, и похоже, что это можно комбинировать с хаком sessionStorage, показанным здесь, для определения направления, но это все равно будет не полностью работает в отношении назад/вперед со страниц из других приложений.
Я пропустил какой-то очевидный способ сделать это?
Вот пара демонстрационных страниц (a и b). Этот пример мутирует по тайм-ауту для простоты. Цель состоит в том, чтобы эффективно удалить измененную страницу A из истории после того, как пользователь уйдет с A таким образом, чтобы кнопки «назад» и «вперед» работали правильно при переходе между сайтами (если бы можно было явно редактировать историю, я бы вероятно, сделайте это в обработчике скрытия страниц).
Страница А:
<html>
<head>
<script>
var originalHTML = 'Original A <a href="pushState_test_page_b.html">page B</a>';
var mutatedHTML = 'Mutated A <a href="pushState_test_page_b.html">page B</a>';
function setMutated() {
document.getElementById('mainContent').innerHTML = mutatedHTML;
}
function setOriginal() {
document.getElementById('mainContent').innerHTML = originalHTML;
}
window.addEventListener('load', function() {
setOriginal();
history.replaceState('original', '');
});
// This timeout is for demo purposes, in my application I mutate to spinner on
// link click
function timeoutHandler() {
setMutated();
history.pushState('mutated', '');
}
setTimeout(timeoutHandler, 3042);
window.addEventListener('popstate', function(evt) {
console.log('event: popstate in ' + window.location);
if ( evt.state !== history.state ) {
throw "evt.state !== history.state"
}
if ( evt.state === null ) {
console.log("evt.state is null");
}
else {
console.log("evt.state is " + evt.state);
switch ( evt.state ) {
case 'mutated':
setMutated();
break;
case 'original':
setOriginal();
break;
default:
throw "unexpected evt.state"
break;
}
}
});
</script>
</head>
<body>
<div id="mainContent">
</div>
</body>
</html>
Страница Б:
<html>
<head>
<script>
window.addEventListener('load', function() {
console.log('event: load (of ' + window.location + ')');
history.replaceState('original', '');
});
window.addEventListener('pageshow', function() {
console.log('event: pageshow of ' + window.location + ')');
console.log(" history.state: " + history.state);
});
window.addEventListener('popstate', function(evt) {
console.log('event: popstate in ' + window.location);
});
</script>
</head>
<body>
<div id="mainContent">
Original B
</div>
</body>
</html>