"beforeunload" support detection

by pmorch

HTML

<h1>A test for "beforeunload" support</h1>
<div>
    "beforeunload" supported:
    <span id="localStorageField"></span>
    /
    <span id="functionValue"></span>
</div>
<p>
    Note that this will only work on the second page loaded from this
    domain! (or the second time you "Run" this jsfiddle)
</p>

JavaScript

/*
    * Testing for beforeunload support *

    Not all browsers support beforeunload :-( In fact,
    quirksmode, the most reliable source for cross-browser
    info, says in
    http://www.quirksmode.org/js/events_events.html:

    > The beforeunload event fires — surprise — just before
    > the unload. Its point is to allow canceling of the
    > unloading of the page, but its use is strongly
    > deprecated. 
   
    You've been warned.

    ** When we need 'beforeunload' **

    Sometimes we actually need 'beforeunload'. See:

    "handle ajax error when a user clicks refresh"
    http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-clicks-refresh

    When issuing an AJAX request, if the user clicks e.g. a
    link while the ajax request is in progress, the error
    callback is called. There is nothing in the AJAX request
    callback parameters, that allows us to detect that this
    AJAX call errored because of a user action: Clicking a
    link to navigate away from the page.

    So instead, when beforeunload is called, we set a
    boolean flag, and then in the AJAX error callback, we
    can assume that the error occurred because the user is
    navigating away from the page

    ** How to test for beforeunload support **

    The idea is simple. On the very first page visit, we
    don't actually know yet if beforeunload is supported.
    But on that very first page, we set up both an unload
    and a beforeunload handler. If the beforeunload handler
    fires, we set a flag saying that beforeunload is
    supported (actually beforeunloadSupported = "yes"). When
    the unload handler fires, if the flag hasn't been set,
    we set the flag that beforeunload is _not_ supported.

    In the following we'll use localStorage ( supported in
    all the browsers I care about - see
    http://caniuse.com/namevalue-storage ) to get/set the
    flag. We could just as well have used a cookie, but I
    chose localStorage because there is...