Warn Users before they Navigate Away from a Page
0
| Languages | JavaScript |
If your page has complicated forms, you might want to warn users before they navigate away from the page or close their browser, and lose everything that they've entered. Because it's kind of annoying when that happens.
1 But how?
The window.unload event fires too late; there is no way to stop the page from unloading once that has fired.
Modern browsers [1] have another event called window.beforeunload that is fired right when any event occurs that would cause the page to unload. This includes clicking on a link, submitting a form, or closing the tab or window. However, this event is implemented completely differently than other javascript events.
2 Using the Event
Like with all javascript events, a handler can be assigned by doing window.beforeunload = handlerFunction.
Warning
MooTools users: for whatever reason, code like window.addEvent('beforeunload', handlerFunction) does not work in Safari 3 (tested with MooTools 1.2).
Most events expect handlers that return a boolean indicating whether or not event propogation should continue. The beforeunload event expects you to return a string.
2.1 Returning a String
If you return a string, the browser places that string inside a dialog box which it shows to the user. For example, this code...
1function closeEditorWarning(){
2 return 'It looks like you have been editing something -- if you leave before submitting your changes will be lost.'
3}
4
5window.onbeforeunload = closeEditorWarning
... will produce a dialog like this when called:
2.2 Returning null
If your event handler returns null, the event continues to propogate. Effectively, nothing happens.
2.3 Returning Something Else
If something else is returned, the dialog box will still appear, but without the custom text.
Warning
Even if false is returned, the dialog box will appear. To allow actions to proceed without any box, you must return null.
3 Conditionally Displaying the Dialog
Unfortunately, with the above code the dialog box will pop up whenver you try to leave the current page, including by submitting a form. Ideally, you could check which object was clicked inside the event handler, and only display the result if it wasn't, say, a submit button. But of course while that works in Firefox, it doesn't in Safari. So we need another, uglier method.
The best way I have found to do this is to add an onclick event to the elements that you don't want triggering the dialog box when clicked (ie submit buttons) . This event can set a variable telling the beforeunload event not to do anything:
1// Assume 'submit' is already defined as my submit button. I want it, and only it, to *not* fire the beforeunload event
2
3var dont_show_warning = false
4
5function dontShowWarning(){
6 dont_show_warning = true
7}
8
9submit.onclick = dontShowWarning
10
11
12function closeEditorWarning(){
13 // Bail if one of the submits was clicked
14 if (dont_show_warning) return
15
16 return 'It looks like you have been editing something -- if you leave before submitting your changes will be lost.'
17}
18
19window.onbeforeunload = closeEditorWarning
This code will bring up a dialog if you leave the page without pressing the submit button. In fact it is the actual code used on the new snippet page here on Siafoo.
As always, if you have a better way of doing things, please please please edit this article, that is the entire point of Siafoo.
| [1] | I'm not sure exactly which browsers support this event, but I can confirm that Internet Explorer 6 and 7, Firefox 2 and 3, and Safari 3 do, and that Opera 9.5 does not. Sorry Opera users... be careful where you click :( |