How do I retrieve if the popstate event comes from back or forward actions with the HTML5 pushstate?

女生的网名这么多〃 提交于 2019-12-17 07:15:05

问题


I'm developing a webpage where depending on the next or back actions I do the correspondent animation, the problem comes when using the pushstate. When I receive the event how do I know if the user clicked back or forward history buttons using the Pushstate API?, or do I have to implement something myself?


回答1:


You must implement it yourself which is quite easy.

  • When invoking pushState give the data object a unique incrementing id (uid).
  • When onpopstate handler is invoked; check the state uid against a persistent variable containing the last state uid.
  • Update the persistent variable with the current state uid.
  • Do different actions depending on if state uid was greater or less than last state uid.



回答2:


This answer should work with a single page push-state app, or a multi-page app, or a combination of the two. (Corrected to fix the History.length bug addressed in Mesqualito’s comment.)

How it works

We can easily listen for new entries to the history stack. We know that for each new entry, the specification requires the browser to:

  1. “Remove all the entries in the browsing context’s session history after the current entry”
  2. “Append a new entry at the end”

At the moment of entry, therefore:

new entry position = position last shown + 1

The solution then is:

  1. Stamp each history entry with its own position in the stack
  2. Keep track in the session store of the position last shown
  3. Discover the direction of travel by comparing the two

Example code

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

See also a live copy of the code.

Limitation

This solution ignores the history entries of external pages, foreign to the application, as though the user had never visited them. It calculates travel direction only in relation to the last shown application page, regardless of any external page visited in between. If you expect the user to push foreign entries onto the stack (see Atomosk’s comment), then you might need a workaround.



来源:https://stackoverflow.com/questions/8980255/how-do-i-retrieve-if-the-popstate-event-comes-from-back-or-forward-actions-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!