How to determine if a user was taken to a page using the back button?

This question is similar to Track when a user clicks a button in a browser , but not the same ... I have a solution and I post it here for reference and feedback. If anyone has the best options, I'm all ears!

The situation is that I have a page with in-place editing, a la flickr. That is, "click here to add a description" of the DIV, which when clicked turns into TEXTAREA with the "Save" and "Cancel" buttons. Clicking "Save" saves the data on the server for updating the database and places the new description in the DIV instead of TEXTAREA. If the page is refreshed, the new description is displayed in the database with the "click to edit" option. Decently standard web 2.0 these days.

The problem is that if:

  • page loads without description
  • description added by user
  • the page will move by clicking the link
  • user clicks the back button

Then what is displayed (from the browser cache) is a version of the page without a dynamically modified DIV containing a new description.

This is a pretty big problem, as the user assumes that their update has been lost and will not necessarily understand that they need to refresh the page to see the changes.

So, the question arises: how can you mark a page as changed after loading it, and then determine when the user will β€œreturn to it” and force refresh in this situation?

+70
browser ajax back-button
May 6 '09 at 10:48
source share
9 answers

Use a hidden form. The form data is saved (usually) in browsers when you reload or click the "Back" button to return to the page. The following is shown on your page (perhaps below):

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

In your javascript you will need the following:

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

The js that sniffs the form should complete after a full html analysis, but you can put both the form and the js line at the top of the page (js second) if user latency is a serious concern.

+72
Apr 12 2018-11-11T00:
source share

This article explains this. See the following 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> 
+10
Jun 15 2018-11-22T00:
source share

Here is a very simple modern solution to this old 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 is currently supported by all major browsers.

+9
Aug 24 '17 at 9:31 on
source share

As mentioned above, I found a solution and post it here for reference and feedback.

The first step in the solution is to add the following to the page:

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

The contents of fresh.html not important, so enough:

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

When the client-side code refreshes the page, you must change it as follows:

 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 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 does all the work: when it is loaded, it calls the reload_stale_page function, which will refresh the page if necessary. At the first load (i.e., after making changes, the reload_stale_page function reload_stale_page do nothing.)

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

From my (minimal) testing at this point, this seems to work as it wants. Did I miss something?

+2
May 6 '09 at 11:07
source share

You can use localStorage or sessionStorage ( http://www.w3schools.com/html/html5_webstorage.asp ) to set a flag (instead of using a hidden form).

+2
Jun 02 '16 at 14:29
source share

You can solve this problem using the onbeforeunload event:

 window.onbeforeunload = function () { } 

The presence of the onbeforeunload function of an empty event dispatcher means that the page will be rebuilt every time it is accessed. Javascripts will be re-launched, server-side scripts will be re-launched, the page will be built as if the user first hit it, even if the user got to the page by simply clicking the "Back" or "Forward" button

Here is the complete example code:

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

Try it, go from this page, and then go back using the "Back" or "Forward" buttons in your browser.

It works great in IE, FF, and Chrome.

Of course, you can do whatever you want inside myfun .

Additional information: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

+1
Jun 04 '15 at 4:05
source share

Using this page, especially considering @sajith's comment about @Nick White's answer and this page: 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
Feb 26 '16 at 4:20
source share

Today I ran into a similar problem, and I solved it using localStorage (here with a bit of 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 mainly:

On page 1, when the user submits the form, we set the value of "steps" to localStorage to indicate which step the user took. At the same time, we run a function with a timeout, which checks whether this value has been changed (for example, 10 times / sec).

On page 2, we will immediately change the indicated value.

Therefore, if the user uses the "Back" button, and the browser restores page 1 to the exact state when we left it, the checkSteps function still works and can detect that the value in localStorage has been changed (and may take appropriate measures). Once this check fills its target, there is no need to continue to run it, so we just no longer use setTimeout.

0
Jun 08 '16 at 15:29
source share

Here is the jQuery version. I had to use it several times due to the way the Safari desktop / mobile phone handles the cache when the user clicks the back button.

 $(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { // Loading from cache } }); 
0
Mar 31 '17 at 14:20
source share



All Articles