JavaScript - bfcache/pageshow événement - événement.persisted toujours mis à false?

dans une application Web Java / SpringMVC / JSP / jQuery standard, j'essaie de détecter un" retour " (Ou historique.go (-1)), afin de rafraîchir (AJAX) un contenu de component/panel de résumé quand je retourne à une page (où nous pouvons changer les données de backend qui est affiché par le component de résumé).

j'ai essayé ce qui suit en JavaScript (en suivant certains messages sur StackExchange sur la façon d'y parvenir):

<script type="text/javascript">
$(document).ready(function() {
    window.onpageshow = function(event) {
        console.log("Event:");
        console.dir(event);
        if (event.persisted) {
            alert("non-jQuery - back to page - loaded from bfcache");
        } else {
            alert("non-jQuery - loaded page from server");
        }
    };
    $(window).on("pageshow", function(event){
        console.log("Event:");
        console.dir(event);
        if (event.originalEvent.persisted) {
            alert("jquery - back to page - loaded from bfcache");
        } else {
            alert("jquery - loaded page from server");
        }
    });
});
</script>

J'exécute OpenSUSE Linux et J'ai essayé cela avec FireFox et Chrome (dernières versions), mais chaque fois que l'attribut persisted de l'événement est défini à false (je peux le voir dans la console JavaScript et par les alertes qui apparaissent à partir du code ci-dessus). Par chaque fois, je veux dire, indépendamment du fait qu'il ait été chargé à partir du serveur ou montré à nouveau via le bouton Back (ou un lien 'Back').

mon intention était de faire un appel AJAX pour recharger le composant/panneau de résumé avec les données mises à jour de la serveur si la page s'affichait via le bouton Précédent ou l'appel history.go(-1) .

j'ai également essayé de configurer un gestionnaire de déchargement (qui ne fait rien) pour empêcher la page d'être mise dans la bfcache mais il semble toujours afficher une version BF-cached et le event.persisted (ou event.originalEvent.persisted ) est défini à false .

cette propriété est-elle gérée correctement sur Linux? Est-ce que je fais quelque chose de stupide dans mon code? N'importe quelle aide ou des idées seraient très appréciées, merci!

6
demandé sur Eoin 2013-07-02 22:16:12

4 réponses

cela semble être un bug dans Chrome (aussi présent dans IE11 ).

j'ai trouvé la solution suivante:

<input type="hidden" id="cacheTest"></input>
<script>
  var input = document.querySelector('#cacheTest')

  if (input.value === "") {
    // the page has been loaded from the server,
    // equivalent of persisted == false
  }
  else {
    // the page has been loaded from the cache,
    // equivalent of persisted == true
  }

  // change the input value so that we can detect
  // if the page is reloaded from cache later
  input.value = "some value"
</script>

ceci exploite le fait que dans la plupart des navigateurs, lorsque la page est chargée à partir du cache, les valeurs des champs de forme sont également conservées.

9
répondu Grégoire Clermont 2014-02-18 15:25:03

j'ai trouvé les boutons d'entrée cachés ne sont pas une solution fiable car ils peuvent tenir la mauvaise valeur quand l'utilisateur navigue de nouveau à la page et puis frappe rafraîchir. Certains navigateurs (Firefox) conservent les valeurs d'entrée sur refresh, donc chaque fois que l'utilisateur clique sur refresh, il va rafraîchir à nouveau car le bouton d'entrée contient la mauvaise valeur. C'est un scénario typique pour les forums (l'utilisateur regarde un sujet, appuie sur le bouton arrière pour revenir à la liste des sujets, et peut continuer à appuyer sur Rafraîchir pour vérifier si il y a de nouveaux sujets).

comme L'a noté Grégoire Clermont, event.persisted est buggy dans chrome (et IE) et cela n'a toujours pas été fixé pour l'un ou l'autre des navigateurs à partir de février 2017. La bonne nouvelle est que vous pouvez compter sur window.performance.navigation.type == 2 pour chrome et IE. Ironiquement, Firefox n'est pas fiable pour ces derniers, mais cela ne devrait pas avoir d'importance puisqu'il est fiable pour event.persisted . Le code suivant a fonctionné pour moi:

if (document.addEventListener) {
    window.addEventListener('pageshow', function (event) {
        if (event.persisted || window.performance && 
            window.performance.navigation.type == 2) 
        {
            location.reload();
        }
    },
   false);
}
5
répondu Tom Davenport 2017-02-06 09:30:26

je sais que c'est un peu tard, mais cela fonctionne pour moi:

window.onpageshow = function(e) {

    if (e.persisted) {

        alert("Page shown");
        window.location.reload();
    }
};

Je ne pense pas que vous en ayez besoin dans la fonction document ready, utilisez simplement vanilla comme ci-dessus.

0
répondu Chez 2014-04-15 21:39:32

gardez le code ci-dessous n'importe où dans le fichier JS. Il restreint le bouton de retour appuyer sur la page (ou le formulaire).

window.onload = function () { window.history.forward(); }

-1
répondu Ramanujam Allam 2015-02-25 06:14:03