'pageshow' is not received when pressing "back" button on Safari on *IPad"
Asked Answered
S

7

15

I have the following handler:

        $(window).bind('pageshow', function() { alert("back to page"); });

When I navigate away from the page (by pressing on a link) and return back to the page (by pressing the "back" button), the alert() is not called (IPad 2, iOS 5.1).

What am I doing wrong please? Any other event I need to bind to?

PS: interesting that pagehide is received properly when navigating away from the page.

Superbomb answered 11/4, 2012 at 13:3 Comment(0)
K
11

You can check the persisted property of the pageshow event. It is set to false on initial page load. When page is loaded from cache it is set to true.

window.onpageshow = function(event) {
    if (event.persisted) {
        alert("back to page");
    }
};

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("back to page");
    }
};
Kavita answered 28/9, 2012 at 23:59 Comment(6)
It appears this is supposed to be the correct answer, but the browsers I have tried (Safari 7 and Firefox 26 on Mac OS 10.9) never set persisted to true, even though they aren't actually reloading from the server. (At this point I'm not even willing to trust their own developer tools, so I used Wireshark to verify. I'm sending cache-control headers to make a page non-cacheable, and Safari claims it's not using the cache, but Wireshark shows no traffic to the server when I click Back.)Debbiedebbra
Something has changed in Safari 7 then. Just tested and event.persisted is set to true in Safari 6.Kavita
It looks like onpageshow event does not trigger at all with 6.1.1. when clicking back button...Kavita
@Debbiedebbra how did you fix it.. I am having the same issue.Mancino
Just leaving a message to let you know this issue persist on Safari for iOS 9.3, no valid answer found yet.Op
@MikaTuupola do you know of a list of all the Safari versions that do not support the persisted check on pageshow? This would allow me to disable nonsupporting versions (via css browser detection) the layer of that spinner I am trying to hide.Deerstalker
C
7

This is likely a caching issue. When you go back to the page via the "back" button, the page is being pulled from the cache (behavior is dependent on the browser). Because of this, your JS will not fire since the page is already rendered in the cache and re-running your js could be detrimental to layout and such.

You should be able to overcome this by tweaking your caching headers in your response or using a handful of browser tricks.

Here are some links on the issue:

EDIT

These are all pulled from the above links:

  • history.navigationMode = 'compatible';
  • <body onunload=""><!-- This does the trick -->
  • "Firefox 1.5+ and some next version of Safari (which contains the fix for bug 28758) supports special events called pageshow and pagehide."
  • Using jQuery's $(document).ready(handler)
  • window.onunload = function(){};
Comatose answered 11/4, 2012 at 13:51 Comment(1)
Thanks. I've suspected that it happens because of the caching issues. Also, IF I am right - the pageload and pagehide are just the "tricks" that are supposed to do the job (but they don't seem to work), can you please be more specific on other tricks I don't know? Ah, and I can't modify the caching headers in my case.Superbomb
E
6

What you're doing there is binding the return value of alert("back to page") as a callback. That won't work. You need to bind a function instead:

$(window).bind('pageshow', function() { alert("back to page"); });
Exodontics answered 11/4, 2012 at 13:15 Comment(2)
sorry, thanks for the correction - tried it as well with no success (actually, my home-brewed example included a callback function, not the actual call). main question edited.Superbomb
Finally, something that worked for the iPhone Safari back button. Thanks.Mariandi
V
2

I add the same problem where iOS does not always post the "pageshow" event when going back.

If not, safari resumes executing JS on the page so I though a timer would continue to fire.

So I came with this solution:

var timer;

function onPageBack() { alert("back to page"); }

window.addEventListener('pageshow', function() {
    if (event.persisted)
        onPageBack();

    // avoid calling onPageBack twice if 'pageshow' event has been fired...
    if (timer)
        clearInterval(timer);
});

// when page is hidden, start timer that will fire when going back to the page...
window.addEventListener('pagehide', function() {
    timer = setInterval(function() {
        clearInterval(timer);
        onPageBack(); 
    }, 100); 
});
Vasiliki answered 17/2, 2020 at 15:11 Comment(0)
E
0

I solved that issue like that;

$(window).bind("pageshow", function () {

    setTimeout(function () {
        back();
    }, 1000);

});

function back() {
   //YOUR CODES
}
Equimolecular answered 27/11, 2019 at 12:16 Comment(2)
Will this coded still work for Safari if having multiple iFrames. See @Bob's comment 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. ?Deerstalker
I'm not sure, and this was a very old situation for me. Unfortunately, you should try it to be sure.Dermatome
S
0

you should checkout you page is has iFrame component? i dont know why , but i delete iFrame component to solve this question

Spirometer answered 29/5, 2020 at 11:8 Comment(0)
D
0

The only way I got this to work across ALL web browsers is to disallow the caching of the page you are returning to. I know -- it is a bit radical; it would be nice to get it to work using JavaScript, but I could figure it out.

I added a Cache-Control header in my .asp pages a helpful list of most options available to add the header..

My test.asp page

<%@language="VBSCRIPT" CODEPAGE="65001" LCID=1033%>
<%
Option Explicit
SetLocale(1033)
Response.ContentType = "text/html"
Response.CharSet = "UTF-8"

Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
Response.addHeader "Expires", "0" ' Proxies.
    
%><html>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<style>
body {margin: 50px auto;text-align: center;}
a {padding: 5px;}
#spinner {width: 100%;height: 100%;background: green;position: absolute;top: 0;display:none;}
</style>
<head>
</head>
<body style="min-height: 100vh;">
Hello World!<br>
<h3 id="pagevalue"></h3>
<a href="test.asp?page=1" onclick="showSpinner();">page 1</a>
<a href="test.asp?page=2" onclick="showSpinner();">page 2</a>
<a href="test.asp?page=3" onclick="showSpinner();">page 3</a>
<div id="spinner"></div>
<script>
function showSpinner(){
    document.getElementById("spinner").style.display = "block";
}
var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = window.location.search.substring(1),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
        }
    }
    return false;
};
document.getElementById("pagevalue").innerHTML = "page "+getUrlParameter("page");
</script>
</body>
</html>

To complete your

alert("back to page")

request, I suggest you add a tracking mechanism that keeps track of the clicks.

Deerstalker answered 29/1, 2023 at 0:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.