HEY! Are you SURE you wanted to leave?

It's a de facto standard these days: if you have a form that may take the user a long time to fill out, you ask them if they meant to leave before actually letting them go.

Needless to say, this is ugly, obtrusive, and all-around undesirable.

I had a need for such functionality, but didn't like the method that I was most familiar with (some trickery involving window.onunload or window.onbeforeunload). So I began searching to see what the latest "best practices" on the topic were.

I should've known better.

The SO question that I came across, Best way to ask confirmation from user before leaving the page?, was answered by the resounding pleas of developers everywhere to not implement such a thing. Overall, I felt the responses were mostly specific to the asker's use case (preventing the user from leaving a registration form unintentionally), but then I read Oli's answer, the topic and gist of which was:

Never prevent the user, only help them.

So the question is not "How to prevent the user from accidentally leaving the page", but "How to help the user if they accidentally leave the page". And whole new thought processes opened up.

What are we helping them with? Since the use case is a form that takes a while to fill out -- or where changes are generally difficult to reproduce -- we primarily want to help them recover those changes.

Now, how do we do that?

For most forms, this is as simple as serializing the form's contents to a cookie or backend session periodically while the user is on the page. Don't worry about them leaving the page. If their data is saved, just load it back in when they come back -- which will likely be a few seconds later, if they did leave accidentally. (Incidentally, Oli goes on to describe this method in his answer).

What if space might be an issue, or if saving the whole form is a bad idea (say, I don't know, a collaborative novel-writing app)? There are plenty of diff algorithms out there. Some are already implemented in javascript. Simply store the original locally and save out a diff perodically. Then make an honest attempt to merge the diff back into the current version when they come back from "accidentally leaving." Heck, at this point, you might as well do live-editing Google Docs style.

However you do it, the data doesn't need to be stored permanently: if the user leaves the page long enough for the cookie/session to expire, chances are they're not coming back to that content. And a "Wait, don't go!" dialog isn't going to prevent them from leaving, either.

Or, as Oli put it:

If they don't come back and their cookie/session expire, that's their fault. You can only lead a horse to water. It's not your job to force it to drink.