37

The issue I've found is very similar to this question, except that Safari on desktops seems to have resolved the issue. Essentially, the issue is this: when a client is browsing on mobile safari and the page executes a javascript function on pageA.html, then navigate to pageB.html, then press the back button to go back to pageA.html, the javascript function won't run when the client pressed the back button to come back to pageA.html. It will skip the javascript call.

I've tried the solutions mentioned in the link above, but nothing seems to work for mobile Safari. Has anyone else encountered this bug? How did you handle it?

user487772
  • 8,800
  • 5
  • 47
  • 72
Sal
  • 3,179
  • 7
  • 31
  • 41
  • 2
    You might want to try appending all link URLs with `?` if it's not yet present. e.g.: `href="next.html"` become `href="next.html?"`. This would give a hint to the web browser that the page content is dynamic and going to that page again should reload the page from the server again. This should be applied to external scripts also. e.g.: `src="mylib.js"` become `src="mylib.js?"`. – Jay Sep 18 '12 at 06:52

1 Answers1

94

This is caused by back-forward cache. It is supposed to save complete state of page when user navigates away. When user navigates back with back button page can be loaded from cache very quickly. This is different from normal cache which only caches HTML code.

When page is loaded for bfcache onload event wont be triggered. Instead you can check the persisted property of the onpageshow event. It is set to false on initial page load. When page is loaded from bfcache it is set to true.

window.onpageshow = function(event) {
    if (event.persisted) {
        alert("From back / forward cache.");
    }
};

For some reason jQuery does not have this property in the event. You can find it from original event though.

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
      alert("From back / forward cache.");
    }
});

Quick solution to these problem is to reload the page when back button is pressed. This however nullifies any positive effect back / forward cache would give.

window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};

As a sidenote, you can see lot of pages offering using empty onunload handler as solution. This has not worked since iOS5.

$(window).bind("unload", function() { });
Andrey
  • 59,039
  • 12
  • 119
  • 163
Mika Tuupola
  • 19,877
  • 5
  • 42
  • 49
  • 5
    It should be noted that this solution no longer works on current versions of iOS (I believe I read somewhere it was anything beyond 5ish). pageshow event will fire for the first back/forward, and never again for that page history state. The only viable solution I've found beyond that is to utilize popstate event to identify back/forward. – Shiboe May 29 '14 at 17:41
  • 2
    It is the empty onunload handler which has not worked since iOS5. The answer above works for iOS6. Not sure about iOS7 though. Will test a bit later. – Mika Tuupola May 30 '14 at 08:38
  • 1
    This works on iOS7, but also has the side-effect of refreshing the page if the screen is turned off and turned back on again. Any way to get around that? – Dave4988 Sep 08 '14 at 15:18
  • The 1st option worked for me i just needed to reset the styles of a certain element. - are there any other mobile browsers with persistance? – Flakx Sep 15 '14 at 16:13
  • 7
    I'm sorry, but this is not working for me on OSX and Safari. event.persisted is always false. Am I doing something wrong? – MadKian88 Jan 13 '15 at 19:48
  • Just tried this solution on iPad iOS 8.4.1 Works like a charm! – larrydalmeida Sep 16 '15 at 09:42
  • 2
    As far as I can determine, this doesn't work in modern browsers. Inserted the code into the `` and either `console.log()` or `alert()` the `event.persisted` value, and it always returns false. Tested in FF 54 & Chrome 59 on Windows and Safari on iOS 10.3.2 - doesn't work on any of them. – indextwo Jul 25 '17 at 11:29
  • There is a bug in Safari as documented here: https://bugs.webkit.org/show_bug.cgi?id=156356 The Safari "pageshow" / "pagehide" events don't get fired more than once IF an iFrame is present on the page. In my case it's the Facebook "Like button" iFrame. Pretty annoying! – Bob Nov 19 '19 at 09:51