web-dev-qa-db-fra.com

Lorsque le bouton de retour déclenche popState, comment puis-je empêcher une actualisation de page?

J'essaie de modifier le contenu de ma page sans recharger. Actuellement, mon code se lit comme suit:

window.onpopstate = function(event){
    // Ajax Request the Page and replace content with new content
};

Cela fonctionne lorsque je pousse un état puis déclenche l'événement popstate, mais si j'appuie sur le bouton de retour dans le navigateur, il accède à l'url au lieu d'appeler mon événement onpopstate. Comment puis-je empêcher une actualisation de page et mettre à jour la page avec mon appel ajax à la place?

edit: J'essaie de mettre à jour avec pushState et popstate. J'espérais garder mes URL sans hachage.

25
GhotiPhud

Vous devez vous assurer qu'il y a toujours un état d'historique que vous avez poussé à partir de la page actuelle sur l'historique pour empêcher le bouton de retour d'effectuer un chargement de page.

Si vous essayez de garder l'utilisateur "contenu" dans votre application Web afin que le bouton de retour fournisse toujours une sorte de fonction, vous devez pousser au moins deux états sur la pile, puis assurez-vous de pousser un autre état à partir de votre gestionnaire popstate .

var foo = {foo: true}; // state object
history.pushState(foo, "unused argument", "#newInitialUri");
...
var bar = {bar: true}
history.pushState(bar, "unused argument", "#newStateOfWebApp");
...
window.onpopstate = function(event){
    ...
    var baz = {baz: true}
    history.pushState(baz, "unused argument", "#baseState");
};

Dans l'exemple ci-dessus, disons que nous avons chargé '/'. Le script commence à s'exécuter et l'URI de la fenêtre du navigateur devient '/ # newInitialUri' mais aucun chargement de page ne se produit. Puis immédiatement après, l'URI du navigateur devient "/ # newStateOfWebApp" et aucun chargement de page ne se produit.

L'utilisateur appuie sur le bouton de retour de son navigateur. Votre gestionnaire de popstate tire. Pendant votre gestionnaire, event.state est égal à foo et l'uri du navigateur est '/ # newInitialUri'. Aucun chargement de page ne se produit. Le gestionnaire termine de terminer, appelant history.pushState et maintenant l'URI du navigateur est '/ # baseState'. Aucun chargement de page ne se produit. Si l'utilisateur clique à nouveau en arrière, votre événement popstate se déclenchera à nouveau, event.state sera égal à foo (encore), l'uri du navigateur sera '/ # newInitialUri' (pas de chargement de page) et puis ce sera à nouveau '/ # baseState' (pas de chargement de page).

La chose importante à retenir est que le event.state dans votre gestionnaire popstate contient toujours l'objet d'état pour l'URI que vous venez de revenir à, pas celui que vous venez de recevoir de. C'était déroutant pour moi au début, mais c'était logique quand j'y pensais. Par exemple, l'utilisateur peut être revenu sur votre page après avoir peut-être quitté Google. L'objet d'état est votre opportunité de communiquer le statut de votre application à votre code.

Gardez à l'esprit que certains navigateurs déclenchent l'événement popstate au chargement de la page (ce qui est censé se produire selon les spécifications de ma compréhension). Assurez-vous de vérifier votre objet d'état dans votre gestionnaire avant d'exécuter votre code pour vous assurer de ne pas exécuter de code que vous n'avez pas l'intention de charger sur une page.

Une dernière remarque: si vous utilisez jQuery pour gérer des événements, vous devrez utiliser event.originalEvent.state pour faire référence à l'objet d'état.

29
peabody

Cela peut aider

L'événement nload est envoyé à l'élément window lorsque l'utilisateur s'éloigne de la page. Cela pourrait signifier l'une des nombreuses choses. L'utilisateur aurait pu cliquer sur un lien pour quitter la page ou saisir une nouvelle URL dans la barre d'adresse. Les boutons avant et arrière déclencheront l'événement. La fermeture de la fenêtre du navigateur entraînera le déclenchement de l'événement. Même un rechargement de page créera d'abord un événement de déchargement.

Référence

http://api.jquery.com/unload/

non testé

    $(window).unload(function(e){    
        e.preventDefault();
        $(window).trigger('popstate ');      

    });    

    $(window).bind('popstate ',function(){

   //your ajax call here 
    });

et enfin voici un DÉMO cliquez sur le bouton de retour du navigateur pour le voir fonctionner

mise à jour

vous avez raison le déchargez être annulé mais vous pouvez faire quelque chose comme

$(window).unload(function(e){
    e.preventDefault();
    $(window).trigger('beforeunload');   

});


$(window).bind('beforeunload',function(){

alert('call your ajax here');
    return '';
});

encore une autre DEMO

1
Rafay