w3schools replacestate onpopstate mdn ejemplo change javascript html5 browser-history pushstate

javascript - replacestate - ¿Cómo recupero si el evento popstate proviene de acciones anteriores o posteriores con el pushstate HTML5?



window history replacestate({} (2)

Estoy desarrollando una página web en la que, dependiendo de las acciones siguientes o posteriores, hago la animación correspondiente, el problema se produce cuando se utiliza el pushstate. Cuando recibo el evento, ¿cómo puedo saber si el usuario hizo clic atrás o reenvió los botones del historial utilizando la API Pushstate ?, ¿o tengo que implementar algo por mi cuenta?


Aquí hay una respuesta generalizada. Este enfoque debería funcionar con aplicaciones de una sola página, de estado push; pero también con aplicaciones tradicionales de varias páginas, o combinaciones de las dos.

Cómo funciona

  1. Estampa cada entrada del History con su propia posición en la pila.
  2. Estampa la sesión con la última posición mostrada.
  3. Descubre la dirección del viaje comparando los dos

La clave es esta: podemos detectar cuándo se agregan nuevas entradas a la pila de historial; y como es una pila, conocemos su posición en ese momento: están en la parte superior.

Código de ejemplo

function reorient() // after a position change in the history stack { let state = history.state; let direction; /* (-1, 0, 1) = (backward, reload, forward) position of this entry vs. last entry (of ours) shown */ if( state === null ) // then this entry is new to the stack { const position = history.length - 1; // top of stack direction = 1; // (1) Stamp the entry with its own position in the stack state = String( position ); history.replaceState( state, /*no title*/'''' ); } else // this entry was pre-existing { const position = Number( state ); const stateLastShown = sessionStorage.getItem( ''stateLastShown'' ); const positionLastShown = Number( stateLastShown ); direction = Math.sign( position - positionLastShown ); } // (2) Stamp the session with the last position shown sessionStorage.setItem( ''stateLastShown'', state ); // (3) Answer the question console.log( ''travel direction was '' + direction ); } addEventListener( ''pageshow'', reorient ); // includes initial load addEventListener( ''popstate'', reorient ); // same-page hash changes

Limitación

Esta solución ignora las entradas del History de páginas ajenas a la aplicación, como si nunca hubieran sido visitadas. La dirección del viaje se calcula solo en relación con la última página de la aplicación mostrada, independientemente de cualquier página extranjera que se haya visitado en el medio. Entonces, si espera que el usuario esté inyectando entradas extranjeras en la pila (por ejemplo, vea el comentario de Atomosk), es posible que deba tomar precauciones.


Debe implementarlo usted mismo, que es bastante fácil.

  • Al invocar pushState al objeto de datos un ID único de incremento (uid).
  • Cuando se onpopstate controlador onpopstate ; verifique el uid estatal contra una variable persistente que contenga el último uid estatal.
  • Actualice la variable persistente con el estado actual uid.
  • Realice diferentes acciones dependiendo de si el uid del estado fue mayor o menor que el último uid del estado.