If you are loading your mobile application from the home screen you probably noticed that as soon as you minimize the application Safari Mobile will not keep track of the last visited page. That means that regardless of the page that you were looking at, the next time you switch back to your application, the browser will reload your application and start over again from the initial page.
The issue is that even if you minimize the application for just a second, the user will have to navigate –again, to the point where he or she left the experience.
A possible solution to this problem is to store the ID or URL of the last visited page inside a browser cookie and check for that value every time that application is initialized. In addition to the last visited page ID/URL you also need to decide for how long you will be tracking this information. If your users spend, for example, 5 min average time visiting your application, you may not want to restore the last visited page if the user comes back a week after his or her last visit. Cookies are particularly handy because you can assign an expiration date that will specify for how long the information will be kept.
Code for saving, editing, and deleting cookies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | var app = {}; app.cookie = { /* set cookies */ setCookie: function(name, value, exp, inMinutes) { var exp = exp == null? 7 : exp; var exdate = new Date(); if(inMinutes != null && inMinutes == true){ exdate.setMinutes(exdate.getMinutes() + exp); } else { exdate.setDate(exdate.getDate() + exp); } var cookieValue = escape(value) + ((exp == null) ? "" : "; expires="+exdate.toUTCString()); document.cookie = name + "=" + cookieValue; }, /* retrieve the value of a cookie */ getCookie: function(name) { var i,x,y,ARRcookies = document.cookie.split(";"); for (i=0;i<ARRcookies.length;i++){ x = ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); x = x.replace(/^\s+|\s+$/g,""); if (x==name){ var value = unescape(y); return value; } } return null; }, /* delete cookies (set expiration time in the past) */ deleleCookie: function() { this.setCookie(name, '', -365); } }; |
var app = {}; app.cookie = { /* set cookies */ setCookie: function(name, value, exp, inMinutes) { var exp = exp == null? 7 : exp; var exdate = new Date(); if(inMinutes != null && inMinutes == true){ exdate.setMinutes(exdate.getMinutes() + exp); } else { exdate.setDate(exdate.getDate() + exp); } var cookieValue = escape(value) + ((exp == null) ? "" : "; expires="+exdate.toUTCString()); document.cookie = name + "=" + cookieValue; }, /* retrieve the value of a cookie */ getCookie: function(name) { var i,x,y,ARRcookies = document.cookie.split(";"); for (i=0;i<ARRcookies.length;i++){ x = ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); x = x.replace(/^\s+|\s+$/g,""); if (x==name){ var value = unescape(y); return value; } } return null; }, /* delete cookies (set expiration time in the past) */ deleleCookie: function() { this.setCookie(name, '', -365); } };
Keep in mind that cookies cannot be retrieved until you refresh the page which is fine for the use case that we are trying to address.
Every time that a page is loaded it fires several events. For the purpose of this example will will focus on the pageshow event. This event fires when the pages is shown which is a good time for us to save our cookie.
1 2 3 4 5 6 7 8 | $(document).bind('pageshow', function(){ // triggered when the page is shown if($.mobile.activePage !== undefined) { var pageId = $.mobile.activePage.attr('id'); // make the cookie expire in 60 min app.cookie.setCookie('lastPage', pageId, 60, true); } }); |
$(document).bind('pageshow', function(){ // triggered when the page is shown if($.mobile.activePage !== undefined) { var pageId = $.mobile.activePage.attr('id'); // make the cookie expire in 60 min app.cookie.setCookie('lastPage', pageId, 60, true); } });
Every time that a page is shown this code will set or update a cookie name lastPage, and it will set the value to the ID of the page (make sure that all your pages have the ID attribute defined).
As I mentioned earlier, when you application is minimized Safari Mobile restart and point to the page from where the homescreen shortcut was created, that is the only page where you need to check the value of the cookie. In other words, every time that Safari Mobile restart your application, you will have to check if the cookie exists, if so, you will have to redirect your application to the last visited page if it is different from the main page.
If the pages that comprise your application are all located in a single file, you can simply use the page ID to redirect to the last visited page. For this example we will need to be able to look up the page URL using the page ID. If the ID stored in the cookie is different than the current page ID, then we will need to redirect the application to the URL associated to the stored ID. Here is how:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* Relate the page ID to the actual page URL */ var pageDictionary = { first: 'page1.html', second: 'page2.html' }; /* method to handle the redirection */ function redirectToLastPage(){ var mainPageId = 'first'; var currentPageId = $.mobile.activePage.attr('id'); var lastPageId = app.cookie.getCookie('lastPage'); // these 3 conditions must be valid: // 1. the cookie must exists (lastPageId != null) // 2. the last pages cannot be equal to the current page (currentPageId && currentPageId) // 3. this code must run only in the main application page (currentPageId == mainPage) if(lastPageId != null && lastPageId != currentPageId && currentPageId == mainPageId){ var pageURL = pageDictionary[lastPageId]; //alert(lastPageId +"\n" + currentPageId +"\n" + mainPageId +"\n" + pageURL +"\n"); $.mobile.changePage(pageURL); } // unbind the function itself to make sure the code executes once regardless of the page that has been loaded $(document).unbind('pagebeforeshow', redirectToLastPage); } /* Before the page is show, check the cookie and the list of URLs */ $(document).bind('pagebeforeshow', redirectToLastPage); |
/* Relate the page ID to the actual page URL */ var pageDictionary = { first: 'page1.html', second: 'page2.html' }; /* method to handle the redirection */ function redirectToLastPage(){ var mainPageId = 'first'; var currentPageId = $.mobile.activePage.attr('id'); var lastPageId = app.cookie.getCookie('lastPage'); // these 3 conditions must be valid: // 1. the cookie must exists (lastPageId != null) // 2. the last pages cannot be equal to the current page (currentPageId && currentPageId) // 3. this code must run only in the main application page (currentPageId == mainPage) if(lastPageId != null && lastPageId != currentPageId && currentPageId == mainPageId){ var pageURL = pageDictionary[lastPageId]; //alert(lastPageId +"\n" + currentPageId +"\n" + mainPageId +"\n" + pageURL +"\n"); $.mobile.changePage(pageURL); } // unbind the function itself to make sure the code executes once regardless of the page that has been loaded $(document).unbind('pagebeforeshow', redirectToLastPage); } /* Before the page is show, check the cookie and the list of URLs */ $(document).bind('pagebeforeshow', redirectToLastPage);
Javascript code: appcropolis.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | var app = {}; app.cookie = { /* set cookies */ setCookie: function(name, value, exp, inMinutes) { var exp = exp == null? 7 : exp; var exdate = new Date(); if(inMinutes != null && inMinutes == true){ exdate.setMinutes(exdate.getMinutes() + exp); } else { exdate.setDate(exdate.getDate() + exp); } var cookieValue = escape(value) + ((exp == null) ? "" : "; expires="+exdate.toUTCString()); document.cookie = name + "=" + cookieValue; }, /* retrieve the value of a cookie */ getCookie: function(name) { var i,x,y,ARRcookies = document.cookie.split(";"); for (i=0;i<ARRcookies.length;i++){ x = ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); x = x.replace(/^\s+|\s+$/g,""); if (x==name){ var value = unescape(y); return value; } } return null; }, /* delete cookies (set expiration time in the past) */ deleleCookie: function() { this.setCookie(name, '', -365); } }; $(document).bind('pageshow', function(){ // triggered when the page is shown var pageId = $.mobile.activePage.attr('id'); // make the cookie expire in 60 min app.cookie.setCookie('lastPage', pageId, 60, true); }); /* Relate the page ID to the actual page URL */ var pageDictionary = { first: 'page1.html', second: 'page2.html' }; /* method to handle the redirection */ function redirectToLastPage(){ var mainPageId = 'first'; var currentPageId = $.mobile.activePage.attr('id'); var lastPageId = app.cookie.getCookie('lastPage'); // these 3 conditions must be valid: // 1. the cookie must exists (lastPageId != null) // 2. the last pages cannot be equal to the current page (currentPageId && currentPageId) // 3. this code must run only in the main application page (currentPageId == mainPage) if(lastPageId != null && lastPageId != currentPageId && currentPageId == mainPageId){ var pageURL = pageDictionary[lastPageId]; //alert(lastPageId +"\n" + currentPageId +"\n" + mainPageId +"\n" + pageURL +"\n"); $.mobile.changePage(pageURL); } // unbind the function itself to make sure the code executes once regardless of the page that has been loaded $(document).unbind('pagebeforeshow', redirectToLastPage); } /* Before the page is show, check the cookie and the list of URLs */ $(document).bind('pagebeforeshow', redirectToLastPage); |
var app = {}; app.cookie = { /* set cookies */ setCookie: function(name, value, exp, inMinutes) { var exp = exp == null? 7 : exp; var exdate = new Date(); if(inMinutes != null && inMinutes == true){ exdate.setMinutes(exdate.getMinutes() + exp); } else { exdate.setDate(exdate.getDate() + exp); } var cookieValue = escape(value) + ((exp == null) ? "" : "; expires="+exdate.toUTCString()); document.cookie = name + "=" + cookieValue; }, /* retrieve the value of a cookie */ getCookie: function(name) { var i,x,y,ARRcookies = document.cookie.split(";"); for (i=0;i<ARRcookies.length;i++){ x = ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); x = x.replace(/^\s+|\s+$/g,""); if (x==name){ var value = unescape(y); return value; } } return null; }, /* delete cookies (set expiration time in the past) */ deleleCookie: function() { this.setCookie(name, '', -365); } }; $(document).bind('pageshow', function(){ // triggered when the page is shown var pageId = $.mobile.activePage.attr('id'); // make the cookie expire in 60 min app.cookie.setCookie('lastPage', pageId, 60, true); }); /* Relate the page ID to the actual page URL */ var pageDictionary = { first: 'page1.html', second: 'page2.html' }; /* method to handle the redirection */ function redirectToLastPage(){ var mainPageId = 'first'; var currentPageId = $.mobile.activePage.attr('id'); var lastPageId = app.cookie.getCookie('lastPage'); // these 3 conditions must be valid: // 1. the cookie must exists (lastPageId != null) // 2. the last pages cannot be equal to the current page (currentPageId && currentPageId) // 3. this code must run only in the main application page (currentPageId == mainPage) if(lastPageId != null && lastPageId != currentPageId && currentPageId == mainPageId){ var pageURL = pageDictionary[lastPageId]; //alert(lastPageId +"\n" + currentPageId +"\n" + mainPageId +"\n" + pageURL +"\n"); $.mobile.changePage(pageURL); } // unbind the function itself to make sure the code executes once regardless of the page that has been loaded $(document).unbind('pagebeforeshow', redirectToLastPage); } /* Before the page is show, check the cookie and the list of URLs */ $(document).bind('pagebeforeshow', redirectToLastPage);
page1.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="apple-mobile-web-app-capable" content="yes"/> <link rel="apple-touch-icon" href="apple-touch-icon.png"> <link rel="apple-touch-startup-image" href="apple-touch-startup-image.png"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script> <script type="text/javascript" src="appcropolis.js"></script> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" /> <title>Page #1</title> </head> <body> <div data-role="page" id="first"> <div data-theme="a" data-role="header" data-position="fixed"> <h3>Page #1</h3> </div><!-- /header --> <div data-role="content"> <a data-role="button" href="page1.html">Page #1</a> <a data-role="button" href="page2.html">Page #2</a> </div><!-- /content --> </div><!-- /page --> </body> </html> |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="apple-mobile-web-app-capable" content="yes"/> <link rel="apple-touch-icon" href="apple-touch-icon.png"> <link rel="apple-touch-startup-image" href="apple-touch-startup-image.png"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script> <script type="text/javascript" src="appcropolis.js"></script> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" /> <title>Page #1</title> </head> <body> <div data-role="page" id="first"> <div data-theme="a" data-role="header" data-position="fixed"> <h3>Page #1</h3> </div><!-- /header --> <div data-role="content"> <a data-role="button" href="page1.html">Page #1</a> <a data-role="button" href="page2.html">Page #2</a> </div><!-- /content --> </div><!-- /page --> </body> </html>
page2.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="apple-mobile-web-app-capable" content="yes"/> <link rel="apple-touch-icon" href="apple-touch-icon.png"> <link rel="apple-touch-startup-image" href="apple-touch-startup-image.png"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script> <script type="text/javascript" src="appcropolis.js"></script> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" /> <title>Page #2</title> </head> <body> <div data-role="page" id="second"> <div data-theme="b" data-role="header" data-position="fixed"> <h1>Page #2</h1> </div><!-- /header --> <div data-role="content"> <a data-role="button" href="page1.html">Page #1</a> <a data-role="button" href="page2.html">Page #2</a> </div><!-- /content --> </div><!-- /page --> </body> </html> |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="apple-mobile-web-app-capable" content="yes"/> <link rel="apple-touch-icon" href="apple-touch-icon.png"> <link rel="apple-touch-startup-image" href="apple-touch-startup-image.png"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script> <script type="text/javascript" src="appcropolis.js"></script> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" /> <title>Page #2</title> </head> <body> <div data-role="page" id="second"> <div data-theme="b" data-role="header" data-position="fixed"> <h1>Page #2</h1> </div><!-- /header --> <div data-role="content"> <a data-role="button" href="page1.html">Page #1</a> <a data-role="button" href="page2.html">Page #2</a> </div><!-- /content --> </div><!-- /page --> </body> </html>
Not registered? Create an Account.
Lost your password? Click here to recover.
Create, customize, and publish mobile web applications using the Appcropolis Mobile Builder.
Get StartedWe offer 1,000's of mobile templates that are fully designed, coded, and ready to use. Learn more.
Download Free Templates
Hi there! I'm trying to implement Your script into my site. Still being rather new to this I am not quite sure how to proceed for my case, in which all pages are single files and do not need to be identified via an additional ID. Or so I think. If I nevertheless give each page a unique ID and use Your script accordingly, it does indeed work, but with this, many pages mean just as many lines of pageDirectory entries, and I'm quite sure that this is unnecessary, right? Thus, even though I think I know that with all pages in separate files it's actually easier, not harder, I sadly don't understand what I have to change in order to make it work. All that needs to be done is to compare the URL stored in the cookie (one could store the URL instead of an ID, right?) with the current one, and then redirect. Like I said, I just don't understand how to make it work without adding 100 lines of ID in the JS for 100 pages. Any help You could give me in this matter would be highly appreciated, as Your script is the only one that's actually been working for me at all. 1000 thanks in advance!
Weckman, Storing the URL of the page instead of the ID sounds like a viable idea. In the end, all what you need is a unique identifier of the last visited page to be able to restore it. You should give it a try. To get the current URL --including the hash tag, you can use
document.location.href
ordocument.URL
Good luck!