Alexander Abramovich
Alexander Abramovich

Reputation: 11458

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

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.

Upvotes: 15

Views: 28874

Answers (7)

MeSo2
MeSo2

Reputation: 466

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.

Upvotes: 0

Alexxxcs2 Null
Alexxxcs2 Null

Reputation: 1

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

Upvotes: 0

Pierre Ayel
Pierre Ayel

Reputation: 21

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

Upvotes: 2

Can &#220;rek
Can &#220;rek

Reputation: 661

I solved that issue like that;

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

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

});

function back() {
   //YOUR CODES
}

Upvotes: 0

Mika Tuupola
Mika Tuupola

Reputation: 20397

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");
    }
};

Upvotes: 11

Brandon J. Boone
Brandon J. Boone

Reputation: 16472

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(){};

Upvotes: 7

Matthew
Matthew

Reputation: 15982

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"); });

Upvotes: 6

Related Questions