Как мне узнать, происходит ли событие popstate от действий «назад» или «вперед» с помощью pushstate HTML5? - PullRequest
54 голосов
/ 24 января 2012

Я разрабатываю веб-страницу, где в зависимости от следующих или обратных действий, которые я выполняю соответствующую анимацию, проблема возникает при использовании pushstate. Когда я получаю событие, как я узнаю, нажал ли пользователь кнопки истории назад или вперед с помощью API Pushstate? Или я должен сам что-то реализовать?

Ответы [ 2 ]

54 голосов
/ 24 января 2012

Вы должны реализовать это сами, что довольно просто.

  • При вызове pushState присвойте объекту данных уникальный инкрементный идентификатор (uid).
  • Когда вызывается обработчик onpopstate; проверьте uid состояния с постоянной переменной, содержащей последний uid состояния.
  • Обновить постоянную переменную текущим состоянием uid.
  • Выполнять различные действия в зависимости от того, был ли uid состояния больше или меньше последнего uid состояния.
3 голосов
/ 16 марта 2018

Этот ответ должен работать с одностраничным приложением push-state, многостраничным приложением или их комбинацией. (Исправлено, чтобы исправить ошибку History.length, указанную в комментарии Мескалито.)

Как это работает

Мы можем легко прослушивать новые записи в стеке истории.Мы знаем, что для каждой новой записи спецификация требует от браузера:

  1. «Удалить все записи в истории сеанса контекста просмотра после текущей записи»
  2. «Добавить новую запись в конце»

Следовательно, в момент входа:

новая позиция входа = последняя отображенная позиция + 1

Тогда решение будет таким:

  1. Пометить каждую запись истории с ее собственной позицией в стеке
  2. Отслеживать в хранилище сессий последнюю показанную позицию
  3. Узнайте направление движения, сравнив два

Пример кода

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

См. Также живую копию кода.

Ограничение

Это решение игнорирует записи истории внешних страниц, чуждых приложению, как если бы пользователь никогда не посещал их.Он рассчитывает направление движения только относительно последней показанной страницы приложения, независимо от того, какая внешняя страница была посещена между ними.Если вы ожидаете, что пользователь поместит чужие записи в стек (см. Комментарий Atomosk), вам может потребоваться обходной путь.

...