Tag Archives: jQuery

Catching the Javascript beforeunload event, the cross-browser way

Javascript’s window.onbeforeunload event is useful for catching users that try to browse away from your page without having completed a certain action. Modern web applications such as Gmail and WordPress have made good use of this event.

Being a non-standard event originally invented by Microsoft back in the IE4 days, window.onbeforeunload has some real quirks, although thankfully every major modern browser does support it.

jQuery Doesn’t Help

Prior to jQuery 4, you couldn’t even bind to $(window).bind('beforeunload') due to a bug that has been fixed.

However, this isn’t your average Javascript event. window.onbeforeunload pops up a native dialog box that provides very little opportunity for customization beyond the text that is displayed to the user. There is no known way to disable this native dialog box and prevent normal behavior.

Tapping into jQuery’s $(window).unload() event doesn’t allow you to prevent the page from being unloaded, and I couldn’t get $(window).bind('beforeunload') to work at all in Firefox 3.6.

The Right Way

The right way turned out to be quite easy using native Javascript code (thanks to the Mozilla Doc Center for the working solution).

For IE and FF < 4, set window.event.returnValue to the string you wish to display, and then return it for Safari (use null instead to allow normal behavior):

window.onbeforeunload = function (e) {
    var e = e || window.event;

    // For IE and Firefox prior to version 4
    if (e) {
        e.returnValue = 'Any string';
    }

    // For Safari
    return 'Any string';
};

jQuery table fade doesn’t work in IE7

While working on an up-and-coming web service, I found that apparently Internet Explorer does not cope well with fading <table> elements using jQuery. Here’s what I was doing:

tbl = $('#primaryColumn table');
loading = $('#primaryColumn .loading');

tbl.fadeTo(300, 0.0, function() {
    loading.show();
        tbl.load('/contacts/{pagination:page}/' + page_num + '?ajax&search={pagination:search}', function() {
        loading.hide();
        tbl.stop().fadeTo(300, 1.0, function() {
            tbl.css('opacity', 'auto');  // removing the CSS opacity rule restores the ClearType anti-aliasing in IE
        });
    });
});

For some reason, the fadeIn(), fadeOut(), and fadeTo() effects do not work on <table> elements in IE, although they work great in Firefox and Opera. This also applies when using animate() to alter the CSS opacity rule (yeah, I tried them all).

As usual, the solution proved to be very easy: don’t animate the <table>, rather, wrap the <table> in a <div> and animate that. The only change required is the first line:

tbl = $('#primaryColumn div#table_div');

Bingo! Another three-hour bug-swatting episode reinforcing my hatred for Microsoft browsers of all versions just concluded.

jQuery hoverIntent plugin

hoverIntent is a plug-in that works like (and was derived from) jQuery’s built-in hover. However, instead of immediately calling the onMouseOver function, it waits until the user’s mouse slows down enough before making the call. Why? To delay or prevent the accidental firing of animations or ajax calls. Simple timeouts work for small areas, but if your target area is large it may execute regardless of intent.