wake-up-neo.com

Wie erkenne ich, ob ein Benutzer über die Schaltfläche "Zurück" zu einer Seite gelangt ist?

Diese Frage ist ähnlich wie Verfolgen, wenn der Benutzer im Browser auf die Schaltfläche "Zurück" klickt , aber nicht dasselbe ... 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. Das heißt Es gibt einen "Klicken Sie hier, um eine Beschreibung hinzuzufügen" -DIV, der sich beim Klicken in eine TEXTAREA mit den Schaltflächen Speichern und Abbrechen verwandelt. Durch Klicken auf Speichern werden die Daten auf den Server übertragen, um die Datenbank zu aktualisieren, und die neue Beschreibung wird anstelle der TEXTAREA in die DIV eingefügt. Wenn die Seite aktualisiert wird, wird die neue Beschreibung in der Datenbank mit der Option "Zum Bearbeiten klicken" angezeigt. Heutzutage ziemlich normales Web 2.0-Zeug.

Das Problem ist, dass wenn:

  1. die Seite wird ohne Beschreibung geladen
  2. der Benutzer fügt eine Beschreibung hinzu
  3. durch Klicken auf einen Link wird die Seite verlassen
  4. der Benutzer klickt auf die Schaltfläche Zurück

Anschließend wird (aus dem Cache des Browsers) die Version der Seite ohne den dynamisch geänderten DIV mit der neuen Beschreibung angezeigt.

Dies ist ein ziemlich großes Problem, da der Benutzer annimmt, dass sein Update 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 nach dem Laden als geändert kennzeichnen und dann erkennen, wann der Benutzer "dorthin zurückkehrt" und in dieser Situation eine Aktualisierung erzwingen?

86
Tom

Verwenden Sie ein verstecktes Formular. Formulardaten bleiben (normalerweise) in Browsern erhalten, wenn Sie neu laden oder auf die Schaltfläche "Zurück" klicken, um zu einer Seite zurückzukehren. Folgendes wird auf Ihrer Seite angezeigt (wahrscheinlich ganz unten):

<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';
}

Das js, das das Formular abfängt, muss ausgeführt werden, nachdem das HTML vollständig analysiert wurde. Sie können jedoch sowohl das Formular als auch das js oben auf der Seite einfügen (js Sekunde), wenn die Benutzerlatenz ein ernstes Problem darstellt.

77
Nick White

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.

44
Bassem

Dieser Artikel erklärt es. Siehe 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>
13
Drew Baker

Sie können es mit dem Ereignis onbeforeunload lösen:

window.onbeforeunload = function () { }

Wenn vor dem Laden eine leere Event-Manager-Funktion vorhanden ist, wird die Seite bei jedem Zugriff neu erstellt. Javascripts werden erneut ausgeführt, serverseitige Skripts werden erneut ausgeführt. Die Seite wird so erstellt, als ob der Benutzer sie zum ersten Mal aufgerufen hätte, auch wenn der Benutzer die Seite nur durch Drücken der Zurück- oder Vorwärts-Taste aufgerufen hat .

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 von dieser Seite weg 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 können Sie in der myfun Funktion alles machen, was Sie wollen.

Weitere Informationen: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

2
Nes

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

2
rerezz

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

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

Wenn clientseitiger 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 erledigt die ganze Arbeit: Wenn es geladen ist, ruft es das reload_stale_page Funktion, die die Seite bei Bedarf aktualisiert. Beim ersten Laden (d. H. Nachdem die Änderung vorgenommen wurde, wird reload_stale_page Funktion macht nichts.)

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

Nach meinen (minimalen) Tests in dieser Phase scheint dies wie gewünscht zu funktionieren. Habe ich etwas übersehen?

2
Tom

Verwenden Sie diese Seite, insbesondere den Kommentar von @sajith zur Antwort von @Nick White und diese 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
nmit026

Hier ist eine jQuery-Version. Ich musste es einige Male verwenden, 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
    }
});
1
Wes

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

$(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 im Grunde:

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

Auf Seite 2 ändern wir diesen Wert sofort.

Wenn der Benutzer die Schaltfläche "Zurück" verwendet und der Browser die Seite 1 in dem Zustand wiederherstellt, in dem sie verlassen wurde, wird die Funktion "checkSteps" weiterhin ausgeführt und kann feststellen, dass der Wert in localStorage geändert wurde (und entsprechende Maßnahmen ergreifen ). Sobald diese Prüfung ihren Zweck erfüllt hat, muss sie nicht weiter ausgeführt werden, sodass wir setTimeout einfach nicht mehr verwenden.

0
s427