Comment puis-je récupérer si l'événement popstate provient d'actions back ou forward avec le pushstate HTML5 ?

StackOverflow https://stackoverflow.com/questions/8980255

Question

Je développe une page Web où, en fonction des actions suivantes ou précédentes, je fais l'animation correspondante, le problème survient lors de l'utilisation du pushstate.Lorsque je reçois l'événement, comment puis-je savoir si l'utilisateur a cliqué sur les boutons d'historique précédent ou suivant à l'aide de l'API Pushstate ?, ou dois-je implémenter quelque chose moi-même ?

Était-ce utile?

La solution

Vous devez le mettre en œuvre vous-même, ce qui est assez simple.

  • Lors de l'invocation pushState donnez à l'objet de données un identifiant incrémentiel unique (uid).
  • Quand onpopstate le gestionnaire est invoqué ;vérifiez l'uid d'état par rapport à une variable persistante contenant le dernier uid d'état.
  • Mettez à jour la variable persistante avec l'uid de l'état actuel.
  • Effectuez différentes actions selon que l'uid de l'état était supérieur ou inférieur au dernier uid de l'état.

Autres conseils

Cette réponse doit fonctionner avec une application push-État de page, ou une application de plusieurs pages, ou une combinaison des deux.(Corrigé pour corriger le History.length bug résolu dans le commentaire de Mesqualito.)

Comment ça fonctionne

Nous pouvons facilement écouter les nouvelles entrées dans la pile historique.Nous savons que pour chaque nouvelle entrée, le spécification nécessite que le navigateur :

  1. "Supprimer toutes les entrées de l'historique de session du contexte de navigation après l'entrée en cours"
  2. "Ajouter une nouvelle entrée à la fin"

Au moment de l'entrée, donc :

nouvelle position d'entrée = dernière position affichée + 1

La solution est alors :

  1. Tamponnez chaque entrée de l'historique avec sa propre position dans la pile
  2. Gardez une trace dans le magasin de session de la dernière position affichée
  3. Découvrez le sens de déplacement en comparant les deux

Exemple de 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

Voir aussi un copie en direct du code.

Limitation

Cette solution ignore les entrées historiques des pages externes, étrangères à l'application, comme si l'utilisateur ne les avait jamais visité.Il calcule la direction de voyage uniquement par rapport à la dernière page d'application montrée, quelle que soit la page externe visitée entre les deux.Si vous vous attendez à ce que l'utilisateur pousse les entrées étrangères sur la pile (voir le commentaire d'Atomosk), vous pourriez avoir besoin d'une solution de contournement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top