Good Sir, Before you UnLoad – cross-browser JavaScript headaches

Sometimes when working with Booking processes and long forms you come across the need to slap that old cross-browser tart, the before-onunload event to warn the user that they appear to be trying to exit the page in a dramatic way (close tab, browse elsewhere) which contradicts the purpose or intentions of the page they’re browsing.

So what can we do to assist our user without being a pest; the old beforeunload dialogue event handler to the rescue.

Before you unload & Why It’s a good job Operas Market Share is Shit

Luckily Microsoft created the before-onunload event back in IE4 and subsequently everyone else consumed it and added into their browsers… well everyone but Opera who instead decide to make the browser behave differently failing to fire these events at all.

Now they say theres a way to ‘activate’ this behaviour within a script, as if its an annoying bit of legacy or something no one should use, by using some¬†proprietary¬†tags (http://www.opera.com/support/kb/view/827/); unfortunately this does sod all in Opera 10, but at least it wont affect too many users eh.

Short and Sweet – The Code

Scenario:

Our user is most of the way through ordering a huge 200inch Goliath TV when they decide to suddenly exit, after the payment page on the Confirmation page. Now at this stage of an order it seems possible that the sudden exit is simply a mistake. Rather than frustrate the user we show a little dialogue box checking if they really intended to leave the page.
Of course we dont want this dialogue button to show if the user tries to go to the next or previous page of the booking journey, so we’ll exclude them by killing the binding onclick.
For the test pages I’ve simply added 3 links, the first two are excluded from the event, the third along with refreshing the page and closing the tab/page will cause the event to fire.

What it should do:

  • When the user clicks on “Go to Google (this should cause a popup)” link the dialogue should show
  • When the user clicks to close the tab the dialogue should show
  • When the user clicks refresh (or F5) the dialogue should show
  • When the user clicks either ‘Go to Home’ or ‘Go to Google’ the event should be killed and the page allowed to load

JQuery Fuzziness

<!DOCTYPE html>
<html>
<head>
<title>On Before Unload</title>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
 
<body>
<section>
    <p>The first two links provided should go to their respective targets, the third link should cause the dialogue to appear as should refreshing and trying to exit.</p>
    <a href="/" id="homebtn">Go to Home</a><br />
    <a href="http://google.com" id="googlebtn">Go to Google</a><br />
    <a href="http://google.com">Go to Google (this should cause a popup)</a><br />
</section>
<script>
$(function() {
	/*## JQuery Version ##*/
 
	/* Compatibility Tested ~
	   IE6 - true
	   IE7 - true
	   IE8 - true
	   Chrome 5 + 6 - true
	   Safari(pc) 4.0.x - true
	   Firefox 3.6.x - true
	   Opera 10.53 - false
	*/
	/* References + Notes ~
	 * window.onbeforeunload is an event that fires prior to the unload event when the page is unloaded
	 * MSDN Reference : http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
	 * Moz Reference : https://developer.mozilla.org/en/DOM/window.onbeforeunload
	 * This Event came out in IE4 and isnt in a public specification
	 */
 
	//Bit Of Cross Browser Smashing
	try{
		// http://www.opera.com/support/kb/view/827/
		opera.setOverrideHistoryNavigationMode('compatible');
		history.navigationMode = 'compatible';
	}catch(e){}
 
	//Our Where The F' Are You Going Message
	function ReturnMessage()
	{
		return "WTF!!!";
	}
 
	//UnBind Function
	function UnBindWindow()
	{
		$(window).unbind('beforeunload', ReturnMessage);
	}
 
	//Bind Links we dont want to affect
	$('#homebtn').bind('click', UnBindWindow); 
	$('#googlebtn').bind('click', UnBindWindow); 
 
	//Bind Exit Message Dialogue
	$(window).bind('beforeunload', ReturnMessage);
 
});
</script>
</body>
</html>

If you use JQuery on your site it makes sense to have the above version; it looks a little tidier and most designers would ‘get’ whats going on


DOM DOM DOM

<!DOCTYPE html>
<html>
<head>
<title>On Before Unload</title>
<meta charset="utf-8" />
</head>
 
<body>
<section>
    <p>The first two links provided should go to their respective targets, the third link should cause the dialogue to appear as should refreshing and trying to exit.</p>
    <a href="/" id="homebtn">Go to Home</a><br />
    <a href="http://google.com" id="googlebtn">Go to Google</a><br />
    <a href="http://google.com">Go to Google (this should cause a popup)</a><br />
</section>
<script>
	/* Compatibility Tested ~
	   IE6 - true
	   IE7 - true
	   IE8 - true
	   Chrome 5 + 6 - true
	   Safari(pc) 4.0.x - true
	   Firefox 3.6.x - true
	   Opera 10.53 - false
	*/
	/* References + Notes ~
	 * window.onbeforeunload is an event that fires prior to the unload event when the page is unloaded
	 * MSDN Reference : http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
	 * Moz Reference : https://developer.mozilla.org/en/DOM/window.onbeforeunload
	 * This Event came out in IE4 and isnt in a public specification
	 */
 
	//Bit Of Cross Browser Smashing
	try{
		// http://www.opera.com/support/kb/view/827/
		opera.setOverrideHistoryNavigationMode('compatible');
		history.navigationMode = 'compatible';
	}catch(e){}
 
	//Our Where The F' Are You Going Message
	function ReturnMessage()
	{
		return "WTF!!!";
	}
 
	//UnBind Function
	function UnBindWindow()
	{
		window.onbeforeunload = null;
		return true;
	}
 
	//Bind Links we dont want to affect
	document.getElementById('homebtn').onclick = UnBindWindow;
	document.getElementById('googlebtn').onclick = UnBindWindow;
 
	//Bind Exit Message Dialogue
	window.onbeforeunload = ReturnMessage;
</script>
</body>
</html>

Places this is best implemented

Booking / Payment / Checkout Journey

If your on page x of y and the user suddenly decides to exit, it may be accidental. In this event it makes sense to check with them. Many a time I’ve managed to drop out of a comparison site or booking a holiday when closing pop-ups or the other tabs I was using to check reviews.
Respect your users investment in populating your forms and offer them this event, giving them one last ditch attempt to stop themselves before its too late.

Comment Forms / Email Clients (when populated)

Much the same as with the previous, the user has possibly invested lots of time and didn’t intend to jump out of the page; you can base this on character count or just on the form containing anything. Its one extra click that could save someone hours of time.


Browser Compatibility Table

Browser Works?
IE6 true
IE7 true
IE8 true
Chrome 5 + 6 true
Safari (pc) 4.0.x true
Firefox 3.6.x true
Opera 10.53 false

Labs: Examples (code above)

onbeforeunload in HTML Applications (HTA Files)

To be blunt it doesnt work; and its a known bug IE7 bug… which when your using IE8 the HTA uses IE7′s engine so the bug persists. http://support.microsoft.com/kb/946214

6 thoughts on “Good Sir, Before you UnLoad – cross-browser JavaScript headaches

  1. I struggled with this issue in IE 8 and jQuery for several days. This is the first real working example I could find that actually showed me how to kill the event! Many thanks for your help in posting this.

    James

  2. Is there a way we can also change a counter in a database if user finally chooses to close. I have a need where we need to track a counter for how many pages are open in an application by one user. If I am able to link Jquery return value to database the work is done.

Comments are closed.