Triggering A Popup On Unload

First, let me say that there are very few good reasons to ever use this technique and the last thing I want is to see the re-institution of the popup mania that plagued the web before the advent of the popup blocker. However, you might need to stop the user before they leave your site to inform the user of: unsaved data, an exit survey about your product, something they may have earned/won (I mean really won something, not one of those sign up for 6 things and get an ipod scams), etc. Keep in mind that popups should be used sparingly, as: most people find them annoying, many browsers will automatically block them, and users generally distrust sites with popups. That said, let me explain how best to trigger a popup onunload.

First, most browsers now automatically block popups when not triggered by an anchor tag event, with the exception of the IEs of the world, as any popup not fired by a user action (onclick) are deemed to be malicious. That means that you should inform your users to disable their popup-blockers for your site and let them know that what to expect, or few non-IE users to ever see the popups. That said, the two JavaScript native popups, alert and confirm, will never be blocked and should be used as a first solution whenever possible. For example, suppose you want to inform the user that they have unsaved data:

Example 1: Using Confirm

AHOO.util.Event.on(window, beforeunload, function(e) {
	if (! confirm(You have unsaved data on this page, leave this page? Clicking "yes" to continue will loose your changes forever.)) {
		YAHOO.util.Event.stopEvent(e);
	}
});

To let users know that they have unsaved data, you probably never need anything more than that. However, what if you have a web-service, receiving thousands of unique visitors a day, but only a fraction of those are actually signing up for your service. The biggest question you would have is, what can I do better to reach these potential users. In this case you might consider an exit survey:

Example 2: Exit Survey

YAHOO.util.Event.on(window, beforeunload, function(e) {
	window.open(urlofyoursurvey, surveywindow, status=off,toolbar=off,location=off,menubar=off,directories=off,resizable=off,scrollbars=off,height=800,width=800);
});

FYI: A great, free service for making quick, custom surveys is Survey Monkey.

However, like I said before, this is going to be blocked by the vast majority of browsers. But, did you know there is a better way that most browser will not block:

Example 3: Exit Survey on Anchors

var allowedDomains = [mattsnider.com];

var isAllowedDomain = function(href) {
	for (var i = allowedDomains.length - 1; 0 <= i; i -= 1) {
		if (-1 < href.indexOf(allowedDomains[i])) {
			return true;
		}
	}
	
	return false;
};

var showPopup = function() {
	window.open(urlofyoursurvey, surveywindow, status=off,toolbar=off,location=off,menubar=off,directories=off,resizable=off,scrollbars=off,height=800,width=800);
};

YAHOO.util.Event.on(document, onclick, function(e) {
	var targ = YAHOO.util.Event.getTarget(e);
	
	if (targ.href && ! isAllowedDomain(targ.href) {
			showPopup();
		}
	}
});

In Example 3, we are listening to all clicks on the document, but ignoring everything that is not an anchor tag. The allowedDomain Array and isAllowedDomain test Function are provided for the case where you do not want to show your exit survey if the user navigates to another page of your site (in my case all urls with the domain mattsnider.com). Because we have attached the event to onclick, most browsers will not block this popup, giving you greater visibility among different user segments. However, this technique misses people who navigate away from your site using any means other than clicking on a link. To capture those users you will need to attach an event to the onunload:

Example 4: Exit Survey Onunload

YAHOO.util.Event.on(window, window.onbeforeunload ? beforeunload : unload, function(e) {
	if (0 > YAHOO.util.Event.getPageY(e)) {
		showPopup();
	}
});

First, we are attaching a listener to onbeforeunload or onunload, depending on whether the browser supports onbeforeunload or not. In the callback function we test to see if the Y-coords of the unload event are less than ZERO, because most browsers will return a negative number if the unload event is triggered by any user action above the actual page, but still within the browser (back/forward, changing the url, closing the window/tab, etc.). This way, we wont double trigger the popup if the user leaves the page by clicking on a link. However, Example 4, will be blocked by most popup blockers, and is it is just a fail-safe to try and reach the largest user segment possible.

Lastly, remember not to abuse this knowledge. Please do not place gratuitous popups on your pages (and if you do, definitely, dont credit me for them). Also, keep in mind that I have used YUI for this example, but only for the Event handling methods, which could be easily replaced with a Simple Event Package or your favorite JavaScript Framework.