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): http://raymondcamden.com/demos/2012/jul/17/index.html
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.