Я разрабатываю веб-страницу, где в зависимости от следующих или обратных действий я делаю корреспондентскую анимацию, проблема возникает при использовании pushstate. Когда я получаю событие, как узнать, был ли пользователь щелкнуть назад или переслать кнопки истории с помощью Pushstate API? Или мне нужно что-то реализовать?
Как я могу получить, если событие popstate происходит от обратного или прямого действия с помощью pushstate HTML5?
Ответ 1
Вы должны реализовать его самостоятельно, что довольно просто.
- При вызове
pushState
предоставить объекту данных уникальный инкрементирующий id (uid). - Когда вызывается обработчик
onpopstate
; проверьте состояние uid на постоянную переменную, содержащую последний uid состояния. - Обновить постоянную переменную с текущим текущим состоянием.
- Выполнять различные действия в зависимости от того, было ли состояние uid больше или меньше последнего состояния uid.
Ответ 2
Этот ответ должен работать с одностраничным приложением push-state, многостраничным приложением или их комбинацией. (Исправлено, чтобы исправить ошибку History.length
указанную в комментарии Mesqualitos.)
Как это устроено
Мы можем легко прослушивать новые записи в стеке истории. Мы знаем, что для каждой новой записи спецификация требует от браузера:
- "Удалить все записи в истории сеансов просмотра после текущей записи"
- "Добавить новую запись в конце"
На момент въезда, следовательно:
новая позиция входа = последняя показанная позиция + 1
Решение тогда:
- Пометить каждую запись истории своей позицией в стеке
- Следите в хранилище сеансов последней показанной позиции
- Узнайте направление движения, сравнив два
Пример кода
function reorient() // After travelling in the history stack
{
const positionLastShown = Number( // If none, then zero
sessionStorage.getItem( 'positionLastShown' ));
let position = history.state; // Absolute position in stack
if( position === null ) // Meaning a new entry on the stack
{
position = positionLastShown + 1; // Top of stack
// (1) Stamp the entry with its own position in the stack
history.replaceState( position, /*no title*/'' );
}
// (2) Keep track of the last position shown
sessionStorage.setItem( 'positionLastShown', String(position) );
// (3) Discover the direction of travel by comparing the two
const direction = Math.sign( position - positionLastShown );
console.log( 'Travel direction is ' + direction );
// One of backward (-1), reload (0) or forward (1)
}
addEventListener( 'pageshow', reorient );
addEventListener( 'popstate', reorient ); // Travel in same page
Смотрите также живую копию кода.
ограничение
Это решение игнорирует записи истории внешних страниц, чуждых приложению, как если бы пользователь никогда не посещал их. Он рассчитывает направление движения только относительно последней показанной страницы приложения, независимо от того, какая внешняя страница была посещена между ними. Если вы ожидаете, что пользователь поместит чужие записи в стек (см. Комментарий Atomosks), вам может потребоваться обходной путь.