However, with JavaScript, you can warn the user before they leave the page inappropriately (with the back button or otherwise), explain why it is a really bad idea, and give them a chance to cancel the operation. If they don't cancel... well, you did your best.
I cover exactly how to do this in my article how do I keep the user from leaving the page? I strongly encourage you to read that article now and follow its advice. The rest of this article concerns how to force the user forward again if they do manage to back up - but I really don't encourage the use of this technique. You should use the warning technique instead.
Bouncing the User Forward Again
OK, so you can't completely disable the back button, and the user has backed up anyway. Are we stuck? Not quite: we can force them forward again.If you control all of the pages involved, you can prevent the user from backing up within your site by making sure that pages "bounce" the user forward again when the user backs up to them. And if you're writing a web application in which the user moving backwards is not desirable, then this is exactly what you need.
When Not To Do It
If you are using the technique in my article how do I prevent the user from leaving the page, then the user has already seen a clear warning from you and overridden that warning. That means they really, really want to back up. So don't force the user forward again unless absolutely necessary. It will be seen as obnoxious by the user.How To Do It
OK, you understand the issues. How can you bounce the user forward to the latest page? It's not all that hard to do with JavaScript. There are catches, but I've already sorted them out for you.On the surface, the job is simple. All we have to do is call history.forward() and we're done! Unfortunately, there's a big catch: exactly how and when are we going to call it?
Calling history.forward() from the onLoad handler of the body element sounds like a no-brainer, doesn't it! Unfortunately, many web browsers do not call onLoad when the user backs up to a page. Examples include Safari, Opera, and Firefox (in some situations and not others).
Working Around the onLoad Problem
So what's the solution? Well, all of the browsers that don't call onLoad when you back up to a page do remember the state of any JavaScript timers (setTimeout calls) that were made on that page. Those calls are paused, but the moment you back up to the page, the clock starts ticking again.But how does setTimeout help us? It's very simple. The first time the page loads, onLoad is always called. And we use that to set up our timer... which tries to move forward to the next page in the browser history once every quarter-second. If it can't, we're already on the newest page - not a problem!
So what happens when the user backs up? If they are running Internet Explorer, onLoad is called, history.forward() gets called almost immediately, and we're done. If they are not running IE, then our timer "wakes up," and within a quarter-second history.forward() gets called anyway.
Safari's Bug
It's nice to call history.forward() as part of what we do at onLoad time, because that immediately solves the whole problem for Internet Explorer. Unfortunately, Apple's Safari (at least in the older version 1.2) has a bug that sometimes displays an empty page when this method is used.Fortunately, there is a workaround. As long as we don't try to call history.forward() right away on the first load, but instead set an unnoticeable timer delay (just one millisecond), Safari's "blank page bug" never strikes.
Armed with this information, we can design a page that always pushes the user forward again in every major web browser, including Opera, Safari, Firefox, and Internet Explorer - as long as JavaScript is turned on, of course.
Need to see for yourself? Feel free to try out a simple demo (opens in a new window).
Now, here's the complete code for a simple web page that always "pushes forward" when backed up to:
<html>
<head>
<title>Back Button Demo: Page One</title>
<script>
function backButtonOverride()
{
// Work around a Safari bug
// that sometimes produces a blank page
setTimeout("backButtonOverrideBody()", 1);
}
function backButtonOverrideBody()
{
// Works if we backed up to get here
try {
history.forward();
} catch (e) {
// OK to ignore
}
// Every quarter-second, try again. The only
// guaranteed method for Opera, Firefox,
// and Safari, which don't always call
// onLoad but *do* resume any timers when
// returning to a page
setTimeout("backButtonOverrideBody()", 500);
}
</script>
</head>
<body onLoad="backButtonOverride()">
<h1>Back Button Demo: Page One</h1>
<a href="page2.html">Advance to Page Two</a>
</body>
</html>
"But I need to do other stuff in my onLoad handler!"
Relax! Just separate the calls with semicolons, like this:
backButtonOverride(); someOtherCode();
If you have a lot of code in your onLoad handler, write a function in your head element and just call that instead. It's much easier to read the code that way.
So as a general rule, you must not rely solely on this technique to protect your web applications from dangerous user behavior. If you have created a web application that won't work properly if the user backs up and submits the same form again, then you need to redesign your application. The easiest way to do that is by keeping track of the steps the user has already completed in your database. If the user submits "step three" for the second time, you can display an appropriate error message and then redirect them to the right page for the next uncompleted step.
Better yet, find a way to accept their input and give them the results they had in mind - people back up to change their minds. But there are situations where the back button is truly inappropriate - for example, after deleting an account, or when one has already charged a purchase to a credit card. And this technique is helpful in that situation because the user does not waste time trying to fill out a form you won't be able to accept twice.
Just remember: JavaScript on the browser side is not a substitute for good programming on the server side.
Legal Note: yes, you may use sample HTML, Javascript, PHP and other code presented above in your own projects. You may not reproduce large portions of the text of the article without our express permission.
Got a LiveJournal account? Keep up with the latest articles in this FAQ by adding our syndicated feed to your friends list!
Follow us on Twitter | Contact Us
Copyright 1994-2012 Boutell.Com, Inc. All Rights Reserved.
