Preventing navigation to a page in jQuery Mobile

This post is more than 2 years old.

Here's an interesting situation I ran into recently. Consider a simple web site that begins with a login page. After you successfully login, you proceed to a 'home' page with links to sub pages. But you want to prevent users from using their back button to return all the way to the login page. It isn't a security issue per se, but it is confusing. The user should only be able to go back to the post-login home page.

In theory - this should be simple. jQuery Mobile exposes a pagebeforechange event. As you can guess, it is fired before you change to a page. According to the docs, using preventDefault effectively blocks the loading of the page.

Easy then, right? The docs state that you are passed a data object that contains a "toPage" key. This is either a simple value (url) or a jQuery DOM item for the page. In theory, I can use this to detect someone loading the initial page and simply block it. Here's a snippet of the code I tried:

You can demo this yourself here (opens in new window):

Now, if you try this, something interesting happens. When you click to visit page 2, and then click back in your browser, you will see that the page does not change, but the url does!. So jQuery Mobile kinda "half way" worked but not completely. In testing I saw various problems with this. Just now, I wasn't able to go back anymore, but in other testing I would go back after a second click. It was a bit inconsistent for me.

I posted this to the jQuery Mobile forums and user Kevin B had a great solution. He correctly pointed out that I was preventing jQuery Mobile from navigating but not preventing the browser itself from doing so. He suggested modifying the history directly to correct it. This could be done with a simple history.go(1) statement.

You can see a full example of his solution here. I tried this back in the application I was building and it worked fine. I noticed that in my PhoneGap application that I received a jQuery object instead, but that simply required me doing a quick check on toPage.attr("id").

Hopefully this makes sense and helps others.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Chris Bowyer posted on 7/20/2012 at 3:41 AM

I only have IE8 on my laptop and just get a loading animation

Comment 2 by Raymond Camden posted on 7/20/2012 at 3:46 AM

Could be anything - I made liberal use of console messages for example. I removed them from the code sample to keep things simple. Could be "typeof" too.

Comment 3 by David Fekke posted on 7/25/2012 at 12:51 AM

That is a good example, but I would suggest not using the .live() method. It has been deprecated in JQuery. I would suggest using delegate() or the on() method.

Comment 4 by Raymond Camden posted on 7/25/2012 at 12:54 AM

I've had issues - at times - with .on in jQuery Mobile and page events. But to be fair, I didn't try terribly hard.

Comment 5 by Sarah posted on 1/24/2017 at 5:29 PM

great thank you-works perfect.. I did the following to stop the back button bringing you back to the login page in my app.

$(document).on("pagebeforechange", function(e, ob) {
if (ob.toPage[0].id === "page-login" && ob.options.fromPage) {
console.log("blocking the back");

However after adding this code I noticed that I could not change to the login page at all (for instance when the user logs out).
I solved it so thought i'd share in case anyone needs it.

So in my logOut() function I had to firstly remove the pagebeforechange listener on the document before "changing" to the login page, as follows
function logOut(){
$("#container_wrapper").pagecontainer("change", "#page-login", {transition: 'none'});

Comment 6 (In reply to #5) by Raymond Camden posted on 1/24/2017 at 9:26 PM

Thank you for sharing this.

Comment 7 (In reply to #6) by Sarah posted on 1/25/2017 at 3:19 PM

you're welcome :)