Zach’s ugly mug (his face)

Zach Leatherman

Don’t Let the Door Hit You Onunload and Onbeforeunload

April 22, 2008

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.

Zach’s ugly mug (his face)

Zach is a builder for the web with IndieWeb Avatar for https://www.netlify.comNetlify. He created the IndieWeb Avatar for https://www.11ty.devEleventy site generator and is still fixated on web fonts. His public speaking résumé includes talks in eight different countries at events like IndieWeb Avatar for Conf,btconf’s AvatarBeyond Tellerrand, IndieWeb Avatar for Conference,CSSConf’s AvatarCSSConf, and IndieWeb Avatar for https://www.whitehouse.govThe White House. He is an emeritus of IndieWeb Avatar for https://www.filamentgroup.comFilament Group, nejsconf’s AvatarNEJS CONF, and still helps out with nebraskajs’s AvatarNebraskaJS. Read more about Zach »

Forgive My Feed
10 Replies
    1. Tore B. Krudtaa Disqus

      07 Jun 2009 at 07:05AM
      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:IEFirefoxSafariChromeeven Netscape, but who uses it(did not test any other browsers)
      1. Zach Leatherman Disqus

        09 Jun 2009 at 02:18AM
        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.
        1. 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.
          1. Zach Leatherman Disqus

            13 Aug 2009 at 10:17PM
            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.
            1. 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
              1. Zach Leatherman Disqus

                31 Oct 2009 at 05:11PM
                Hey Ramesh,What browsers are you seeing this behavior in? I know the Safari Blog had some good blog posts about cached pages. 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
                1. 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?
                  1. 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?
                    1. John Biggs Disqus

                      21 Sep 2015 at 12:58AM
                      oNUnlOAd/ONBefoREUNlOAD eVenTS ARE aBuSED SO mUCh By scam/aDvEtISmEnT RiDdEn PAGES THaT thE majoriTy of eNd USERs FinD iT AN ANNoyANCE - i'm GlAD OperA iGnorEs TheSE cALlS
                      1. Disqus

                        02 Jan 2016 at 05:06AM
                        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. Thank you .
                          Social Card Image Preview

                          This is what will show up when you share this post on Social Media:

                          How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)