Don’t Let the Door Hit You Onunload and Onbeforeunload

Many people attempt a last ditch effort to save page state in the browser by using the onunload or onbeforeunload events. This has been studied at great length by Patrick Hunlock, who uses the perhaps now common knowledge of using a Synchronous Ajax call to perform the page state save.

Another use for the onbeforeunload event to allow the user to cancel the action that initiated the user leaving in the first place. Gmail uses this technique when the user is in the middle of writing a draft of an e-mail and attempts to leave the page.


Gmail pops up this prompt when the user attempts to leave the page while drafting an email.

Worthy to note, however, is that Opera doesn’t fire the unload event when the browser refreshes the page, or uses the back/forward buttons to browse off of the page (I had no success with the fix posted in the comments on that page). What’s worse, Opera never fires the onbeforeunload event. This creates a serious problem with attempting to save page state prior to a user leaving your page.

Browser support aside, I believe that the onbeforeunload prompt is not an ideal way to protect the user from lost work (or unsaved page state). Humanized has argued, and I agree, that an undo operation is much easier on the end user than a warning message. The strange thing is, Gmail could save the draft in a synchronous Ajax request in the onunload event. They aren’t using the prompt to save Opera users from losing their drafts, since the Opera web browser doesn’t even fire the onbeforeunload event. (Interestingly enough, they are using some sort of browser history management to fire a warning to the user when they press back, or forward, in Opera — but Reload can’t be caught using this method, so your draft email could be lost).

From a User Interface design standpoint, I would recommend just sticking with onunload. You can still perform your synchronous Ajax call in the method to save the state of your page, so that the user can later resume their state or undo the operation. (Except for Back/Forward/Refresh in Opera, until they support a better onunload or any onbeforeunload). The onbeforeunload prompt is an unnecessary evil, and doesn’t do much besides annoy the end user with another warning message and a mouse click.

This entry was posted in Interface Design, JavaScript, Web Browsers and tagged , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.
  • Hey! Use the magical power of RSS and Subscribe! Send me a tweet or a pull request!
  • Zach Leatherman is a Professional Front End Engineer. He loves building for the web and has been writing here since 2007. Feel free to stalk his résumé.

    He enjoys spending time with his beautiful wife Traci and their two Great Danes, Roxie and Ella. They also have a cat, a rabbit, goldfish, two poison dart frogs, and usually one or more tarantulas. Read more »

8 Comments

  1. Tore B. Krudtaa
    Posted June 7, 2009 at 2:05 am | Permalink

    Here is my view on it.

    Let say you have developed a web application for your customer where the customer is using the web app. on a daily basis in their work.
    And they do not want to loose data or have to retype anything because they forgot to save the page before leaving it.

    They do a lot of entering of new data, changing data in the form etc… before submitting to server.

    Sometimes they actually do forget to save the form/page.

    I have several such web applications for customers where I use the onbeforeunload together with some javascript that test if the form was changed.
    So if the client try to leave a page that has been changed but not saved, then he will get a warning that gives him the option to stay on the page (then he can save the changes), or to continue leaving the page.

    In my opinion the onbeforeunload is a really nice feature.
    And it is a pity that opera has nada support for it.

    Implementing your solution might be doable, but in my opinion it is much better to give the client the choice there and then.
    Using your solution will also cost more for the customer since you will have to write some client and backend code to handle that for each of the forms used.

    Using the onbeforeunload with some javascript to check if the form was changed are supereasy to implement, and only has to be implemented on the client side.

    Why not let the developer choose and pick what he finds best for his application and customer.

    Because of the nada support for onbeforeunload in Opera, in my customers web applications we test which browser and version that client is using when loggin in to the web app. If using Opera then the user is denied access to the site.

    Browsers that have good support for the onbeforeunload event are:
    IE
    Firefox
    Safari
    Chrome
    even Netscape, but who uses it
    (did not test any other browsers)

  2. Zach Leatherman
    Posted June 8, 2009 at 9:18 pm | Permalink

    As with every development decision, you have to weigh the cost of development against the benefit you get. If you think it’s a better cost-benefit to use onbeforeunload, go for it. I just don’t think it’s a very usable solution.

  3. Olivier
    Posted August 12, 2009 at 11:21 am | Permalink

    And what about storing the datas on the client with the new dom storage API instead of the server ? Hoping more browsers will implement this feature soon.

  4. Zach Leatherman
    Posted August 13, 2009 at 5:17 pm | Permalink

    Olivier, that’s a very good idea, if the browser supports it! Considering that most of the modern ones do, it might be worthwhile to store locally if available, and then just use onbeforeunload if not. No sense in doing too much work for those old browsers.

  5. Ramesh
    Posted October 27, 2009 at 12:18 pm | Permalink

    Hi Zach Leatherman,

    The code you put inside the onunload event handler would be executed only after the browser unloads the page. In my case, I have an synchronous AJAX request in unload event. when the user clicks the back button I had to remove the user’s session using that ajax request. But the result is, the browser first send the request to the back button first (previous page) and once its gets the response for the request then only it starts executing the ajax method. I would like to hear your comments on this.

    Thanks,
    Ramesh

  6. Zach Leatherman
    Posted October 31, 2009 at 12:11 pm | Permalink

    Hey Ramesh,
    What browsers are you seeing this behavior in? I know the Safari Blog had some good blog posts about cached pages.
    http://webkit.org/blog/427/webkit-page-cache-i-the-basics/

    In any event, the onunload event should fire before a new page starts loading. Double check the timing, there could be another issue causing the problems you’re seeing.

    Thanks,
    Zach

  7. pratap
    Posted December 14, 2009 at 6:47 am | Permalink

    I found that onbeforeunload in safari is of no use if the window is opened in any of the frames of framesets in parent page. Safari never triggers the onbeforeunload event at all whereas it does triggers this event when not inside any frame.
    Any idea?

  8. Kevin
    Posted August 19, 2011 at 11:44 am | Permalink

    I have found that the ajax code I have placed in onbeforeunload doesn’t always fire (onbeforeunload is firing), so housekeeping doesn’t always get done on the Server. Has anyone come across this? I assume the network connection may be lost, but since the page is closing, is there any way to access any ajax error information?

One Trackback

  1. [...] it’s evil to make it hard for a user to leave a page, I’m not here to argue the merits (or lack thereof) of [...]