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
- Estampa cada entrada del
History
con su propia posición en la pila. - Estampa la sesión con la última posición mostrada.
- 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
controladoronpopstate
; 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.