93 votes

Comment détecter si un utilisateur est arrivé sur une page en utilisant le bouton retour ?

Cette question est similaire à Suivre le moment où l'utilisateur appuie sur le bouton "retour" du navigateur mais pas la même... J'ai une solution et je l'affiche ici pour référence et rétroaction. Si quelqu'un a une meilleure solution, je suis tout ouïe !

La situation est la suivante : j'ai une page avec une "édition en place", à la manière de Flickr. C'est-à-dire qu'il y a un DIV "cliquez ici pour ajouter une description", qui, lorsqu'il est cliqué, se transforme en un TEXTAREA avec des boutons Enregistrer et Annuler. Le fait de cliquer sur Enregistrer envoie les données au serveur pour mettre à jour la base de données et place la nouvelle description dans le DIV à la place du TEXTAREA. Si la page est rafraîchie, la nouvelle description est affichée à partir de la base de données avec une option "cliquer pour modifier". Il s'agit d'une fonctionnalité Web 2.0 assez standard de nos jours.

Le problème est que si :

  1. la page est chargée sans la description
  2. une description est ajoutée par l'utilisateur
  3. On quitte la page en cliquant sur un lien.
  4. l'utilisateur clique sur le bouton retour

Ce qui est alors affiché (à partir du cache du navigateur) est la version de la page sans le DIV modifié dynamiquement contenant la nouvelle description.

C'est un problème assez important car l'utilisateur suppose que sa mise à jour a été perdue et ne comprendra pas nécessairement qu'il doit actualiser la page pour voir les changements.

La question est donc la suivante : comment signaler qu'une page a été modifiée après son chargement, puis détecter le moment où l'utilisateur "y retourne" et forcer un rafraîchissement dans cette situation ?

0 votes

En quoi cela diffère-t-il de la question que vous avez citée ?

0 votes

La question est similaire, mais je pense que l'environnement et donc la réponse sont différents, je peux me tromper. mon interprétation de ce que pourrait être un problème qui serait résolu avec l'autre solution est la suivante : l'utilisateur clique sur un onglet sur une page qui est chargée par ajax, puis sur un autre onglet et ainsi de suite. cliquer sur le bouton retour vous ramènerait à une page différente, pas à l'onglet précédent. ils veulent revenir en arrière à travers "l'historique ajax" dans "l'historique de la page". au moins c'est mon impression de ce que le gestionnaire d'historique du navigateur Yahoo est censé faire.

0 votes

La réponse acceptée comporte votre astuce iframe.

79voto

Nick White Points 1076

Utilisez un formulaire caché. Les données du formulaire sont préservées (en général) dans les navigateurs lorsque vous rechargez ou appuyez sur le bouton Précédent pour revenir à une page. Le texte suivant doit être placé dans votre page (probablement vers le bas) :

<form name="ignore_me">
    <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" />
</form>

Dans votre javascript, vous aurez besoin des éléments suivants :

var dirty_bit = document.getElementById('page_is_dirty');
if (dirty_bit.value == '1') window.location.reload();
function mark_page_dirty() {
    dirty_bit.value = '1';
}

Le js qui renifle le formulaire doit s'exécuter après que le html soit complètement analysé, mais vous pourriez mettre le formulaire et le js en ligne en haut de la page (js en second) si la latence de l'utilisateur est une préoccupation sérieuse.

7 votes

"Les données de formulaire sont préservées (généralement) dans les navigateurs" - pouvez-vous nous en dire plus ? Ne sont-elles pas préservées dans certains navigateurs ? ou dans certaines situations ?

4 votes

En fait, laissez-moi énumérer toutes les façons dont je peux penser que ça va mal se passer. (1) Opera conserve l'état complet de la page et ne ré-exécute pas le js. (2) Si vos paramètres de cache sont modifiés pour forcer la page à se charger depuis le serveur lorsque vous cliquez sur le bouton retour, les données du formulaire peuvent être perdues, ce qui n'est pas un problème dans le cadre de cette question. (3) Les navigateurs des téléphones ont un cache beaucoup plus petit et le navigateur peut avoir déjà supprimé la page du cache (ce qui n'est pas un problème pour cette question).

13 votes

Dans certains navigateurs, les balises cachées ne sont pas conservées. Vous pourriez donc utiliser la balise hidden text au lieu d'utiliser la balise hidden input. <input type="text" value="0" id='txt' name='txt' style="display : none" />

64voto

Bassem Points 129

Voici une solution moderne très simple à ce vieux problème.

if (window.performance && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) {
    alert('Got here using the browser "Back" or "Forward" button.');
}

window.performance est actuellement pris en charge par tous les principaux navigateurs.

13voto

Drew Baker Points 2582

Cet article l'explique. Voir le code ci-dessous : http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/

<html>
    <head>
        <script>

            function pageShown(evt){
                if (evt.persisted) {
                    alert("pageshow event handler called.  The page was just restored from the Page Cache (eg. From the Back button.");
                } else {
                    alert("pageshow event handler called for the initial load.  This is the same as the load event.");
                }
            }

            function pageHidden(evt){
                if (evt.persisted) {
                    alert("pagehide event handler called.  The page was suspended and placed into the Page Cache.");
                } else {
                    alert("pagehide event handler called for page destruction.  This is the same as the unload event.");
                }
            }

            window.addEventListener("pageshow", pageShown, false);
            window.addEventListener("pagehide", pageHidden, false);

        </script>
    </head>
    <body>
        <a href="http://www.webkit.org/">Click for WebKit</a>
    </body>
</html>

1 votes

C'est une bonne réponse, qui fonctionne dans les derniers Chrome 40 / Firefox 35. IE11 ne supporte pas ces événements, cependant.

0 votes

Selon caniuse.com/#feat=page-transition-events les événements de transition de page sont effectivement pris en charge dans IE11+. À l'heure actuelle, la couverture globale de la fonctionnalité est de 88 %.

0 votes

Pour info, Chrome revient event.persisted = false même en appuyant sur le bouton arrière. Vous devez utiliser window.performance.navigation ou PerformanceNavigationTiming pour Chrome.

7voto

Nes Points 51

Vous pouvez le résoudre en utilisant le onbeforeunload événement :

window.onbeforeunload = function () { }

Avoir un onbeforeunload La fonction vide du gestionnaire d'événements signifie que la page sera reconstruite à chaque fois qu'elle sera consultée. Les Javascripts seront ré-exécutés, les scripts côté serveur seront ré-exécutés, la page sera construite comme si l'utilisateur y accédait pour la toute première fois, même si l'utilisateur est arrivé à la page juste en appuyant sur le bouton retour ou avant.

Voici le code complet d'un exemple :

<html>
<head>
<title>onbeforeunload.html</title>
<script>
window.onbeforeunload = function () { }

function myfun()
{
   alert("The page has been refreshed.");
}
</script>

<body onload="myfun()">

Hello World!<br>

</body>
</html>

Essayez-le, quittez cette page et revenez ensuite en utilisant les boutons "Précédent" ou "Suivant" de votre navigateur.

Il fonctionne bien dans IE, FF et Chrome.

Bien sûr, vous pouvez faire ce que vous voulez à l'intérieur myfun fonction.

Plus d'informations : http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

6voto

getup8 Points 3034

Pour les navigateurs modernes, cela semble être la bonne méthode maintenant :

const perfEntries = performance.getEntriesByType('navigation');
if (perfEntries.length && perfEntries[0].type === 'back_forward') {
  console.log('User got here from Back or Forward button.');
}

Il s'agit toujours d'une version "expérimentale" en janvier 2020, mais elle semble être bien supportée.

https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X