Frage Wie erkenne ich, ob ein Benutzer mit der Zurück-Taste auf eine Seite gelangt ist?


Diese Frage ist ähnlich wie Verfolgen, wenn der Benutzer im Browser auf die Schaltfläche "Zurück" klickt, aber nicht das gleiche ... Ich habe eine Lösung und poste sie hier als Referenz und Feedback. Wenn jemand bessere Möglichkeiten hat, bin ich ganz Ohr!

Die Situation ist, dass ich eine Seite mit einem "In Place Edit" habe, a la flickr. I.e. Es gibt ein "Klicken Sie hier, um eine Beschreibung hinzuzufügen" DIV, das, wenn es angeklickt wird, in ein TEXTAREA mit Save und Cancel knöpft. Wenn Sie auf Speichern klicken, werden die Daten auf dem Server gespeichert, um die Datenbank zu aktualisieren, und die neue Beschreibung wird anstelle von TEXTAREA in das DIV eingefügt. Wenn die Seite aktualisiert wird, wird die neue Beschreibung in der Datenbank mit der Option "Klicken zum Bearbeiten" angezeigt. Ziemlich Standard Web 2.0 Sachen in diesen Tagen.

Das Problem ist, dass wenn:

  1. Die Seite wird ohne die Beschreibung geladen
  2. Eine Beschreibung wird vom Benutzer hinzugefügt
  3. Die Seite wird entfernt, indem Sie auf einen Link klicken
  4. Der Benutzer klickt auf die Zurück-Schaltfläche

Was dann angezeigt wird (aus dem Cache des Browsers), ist die Version der Seite ohne das dynamisch modifizierte DIV, das die neue Beschreibung enthält.

Dies ist ein ziemlich großes Problem, da der Benutzer annimmt, dass seine Aktualisierung verloren gegangen ist und nicht unbedingt versteht, dass er die Seite aktualisieren muss, um die Änderungen zu sehen.

Die Frage ist also: Wie können Sie eine Seite als geändert markieren, nachdem sie geladen wurde, und dann erkennen, wann der Benutzer "zurückgeht" und eine Aktualisierung in dieser Situation erzwingen?


76
2018-05-06 10:48


Ursprung


Antworten:


Verwenden Sie ein verstecktes Formular. Formulardaten werden (in der Regel) in Browsern beibehalten, wenn Sie neu laden oder die Zurück-Taste drücken, um zu einer Seite zurückzukehren. Folgendes geht auf Ihrer Seite (wahrscheinlich in der Nähe des unteren):

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

In Ihrem Javascript benötigen Sie Folgendes:

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

Die js, die das Formular schnüffelt, muss ausgeführt werden, nachdem der HTML-Code vollständig analysiert wurde. Sie können jedoch sowohl das Formular als auch die js am Anfang der Seite einfügen (js Sekunde), wenn die Benutzerlatenz ein ernsthaftes Problem darstellt.


73
2018-04-12 22:58



Hier ist eine sehr einfache moderne Lösung für dieses alte Problem.

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 wird derzeit von allen gängigen Browsern unterstützt.


27
2017-08-24 09:31



Dieser Artikel erklärt es. Siehe den folgenden Code: 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>

11
2018-06-15 22:05



Wie oben erwähnt, hatte ich eine Lösung gefunden und poste sie hier als Referenz und Feedback.

Die erste Stufe der Lösung besteht darin, der Seite Folgendes hinzuzufügen:

<!-- at the top of the content page -->
<IFRAME id="page_is_fresh" src="fresh.html" style="display:none;"></IFRAME>
<SCRIPT style="text/javascript">
  function reload_stale_page() { location.reload(); }
</SCRIPT>

Die Inhalte von fresh.html sind nicht wichtig, daher sollte folgendes genügen:

<!-- fresh.html -->
<HTML><BODY></BODY></HTML>

Wenn der clientseitige Code die Seite aktualisiert, muss er die Änderung wie folgt kennzeichnen:

function trigger_reload_if_user_clicks_back_button()
{
  // "dis-arm" the reload stale page function so it doesn't fire  
  // until the page is reloaded from the browser's cache
  window.reload_stale_page = function(){};

  // change the IFRAME to point to a page that will reload the 
  // page when it loads
  document.getElementById("page_is_fresh").src = "stale.html";
}

stale.html macht die ganze Arbeit: Wenn es geladen ist, ruft es die reload_stale_page Funktion, die die Seite bei Bedarf aktualisiert. Das erste Mal, wenn es geladen wird (d. H. Nachdem die Modifikation vorgenommen wurde, wird das reload_stale_page Funktion wird nichts tun.)

<!-- stale.html -->
<HTML><BODY>
<SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT>
</BODY></HTML>

Von meinem (minimalen) Test in diesem Stadium scheint dies wie gewünscht zu funktionieren. Habe ich etwas übersehen?


2
2018-05-06 11:07



Sie können localStorage oder sessionStorage (http://www.w3schools.com/html/html5_webstorage.asp) um ein Flag zu setzen (anstatt ein verstecktes Formular zu verwenden).


2
2018-06-02 14:29



Hier ist eine jQuery-Version. Ich bin dazu gekommen, dass ich es ein paar Mal benutzen muss, da Safari Desktop / Mobile den Cache handhabt, wenn ein Benutzer die Zurück-Taste drückt.

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        // Loading from cache
    }
});

2
2018-03-31 14:20



Sie können es mit Hilfe der onbeforeunload Veranstaltung:

window.onbeforeunload = function () { }

Einen haben onbeforeunload leere Event-Manager-Funktion bedeutet, dass die Seite jedes Mal neu erstellt wird, wenn auf sie zugegriffen wird. Javascripts werden erneut ausgeführt, serverseitige Skripts werden erneut ausgeführt, die Seite wird so erstellt, als ob der Benutzer sie zum ersten Mal getroffen hätte, selbst wenn der Benutzer durch Drücken der Zurück- oder Vorwärts-Taste auf die Seite gelangt ist .

Hier ist der vollständige Code eines Beispiels:

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

Probieren Sie es aus, navigieren Sie diese Seite und kehren Sie dann mit den Schaltflächen "Zurück" oder "Weiter" in Ihrem Browser zurück.

Es funktioniert gut in IE, FF und Chrome.

Natürlich kannst du machen, was du willst mein Spaß Funktion.

Mehr Info: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript


1
2018-06-04 04:05



Mit dieser Seite, insbesondere mit dem Kommentar von @sajith über die Antwort von @Nick White und dieser Seite: http://www.mrc-productivity.com/techblog/?p=1235 

<form name="ignore_me" style="display:none">
    <input type="text" id="reloadValue" name="reloadValue" value="" />
</form>

$(function ()
{
    var date = new Date();
    var time = date.getTime();

    if ($("#reloadValue").val().length === 0)
    {
        $("#reloadValue").val(time);
    }
    else
    {
        $("#reloadValue").val("");
        window.location.reload();
    }
});

1
2018-02-26 04:20



Ich bin heute auf ein ähnliches Problem gestoßen und habe es mit localStorage (hier mit ein bisschen jQuery) gelöst:

$(function() {

    if ($('#page1').length) {
        // this code must only run on page 1

        var checkSteps = function () {
            if (localStorage.getItem('steps') == 'step2') {
                // if we are here, we know that:
                // 1. the user is on page 1
                // 2. he has been on page 2
                // 3. this function is running, which means the user has submitted the form
                // 4. but steps == step2, which is impossible if the user has *just* submitted the form
                // therefore we know that he has come back, probably using the back button of his browser
                alert('oh hey, welcome back!');
            } else {
                setTimeout(checkSteps, 100);
            }
        };

        $('#form').on('submit', function (e) {
            e.preventDefault();
            localStorage.setItem('steps', 'step1'); // if "step1", then we know the user has submitted the form
            checkOrderSteps();
            // ... then do what you need to submit the form and load page 2
        });
    }

    if ($('#page2').length) {
        // this code must only run on page 2
        localStorage.setItem('steps', 'step2');
    }

});

Si grundsätzlich:

Wenn der Benutzer das Formular auf Seite 1 abschickt, legen wir in localStorage einen Wert "steps" fest, um anzugeben, welchen Schritt der Benutzer unternommen hat. Gleichzeitig starten wir eine Funktion mit Timeout, die überprüft, ob dieser Wert geändert wurde (z. B. 10 mal / Sekunde).

Auf Seite 2 ändern wir sofort diesen Wert.

Wenn also der Benutzer die Zurück-Schaltfläche verwendet und der Browser Seite 1 in dem exakten Zustand wiederherstellt, in dem wir ihn verlassen haben, wird die checkSteps-Funktion noch ausgeführt und kann feststellen, dass der Wert in localStorage geändert wurde (und entsprechende Maßnahmen ergreifen kann) ). Sobald diese Überprüfung ihren Zweck erfüllt hat, ist es nicht mehr notwendig, sie weiter auszuführen. Daher verwenden wir setTimeout einfach nicht mehr.


0
2018-06-08 15:29