unload Events in Safari

May 4 2005

Generally I avoid unload event handlers because their behavior is poorly defined. However, I found myself working on a project that necessitated their use. Despite my best efforts, Safari 1.3 (312) and 2.0 (412) appear to ignore my unload event handlers. PPK has made mention of the problem. I’ve found one technique that gets the unload to fire in Safari.

There are three techniques for setting up unload event handlers.

  • Add an onunload attribute to the tag
  • Define the event handler using window.onunload property in JavaScript
  • Call the addEventListener() method as specified in the W3C Dom Level 2 recommendation

If you try the first two unload event techniques with a minimal test case they will not work in Safari. You can look at onunload attribute and JavaScript onunload test cases and verify that they work in non-Safari browsers.

Where it gets interesting is in making the unload work using an addEventListener() method. In the spec every element has an addEventListener() method, but only the BODY and FRAMESET elements allow for an unload event. It sounds simple enough to grab the BODY element and add an unload event listener.

My first impulse was to assign an id in the body tag, something like and then call getElementById('www-rd2inc-com') to get the element and add an unload event. It mostly works in Safari. Safari still doesn’t catch window closes or reloads, but it will catch clicked links and form submissions. However, it does not work in the Mozilla based browsers at all. That problem is currently listed as a bug in bugzilla. A quick browser detect script and now I’ve got slightly crippled unload event handler firing. A test case using addEventListener() is available.

Here is a snippet of the JavaScript to handle setting up the unload event that should work in Firefox, Mozilla, Safari, and Windows IE.

function load() {

if (navigator.userAgent.toLowerCase().indexOf(‘safari’)!=-1) {

var bodyElt;
bodyElt = document.getElementById(“www-rd2inc-com”);

if (!bodyElt) {

bodyElt = document.getElementsByTagName(“body”)[0];

}

if (bodyElt) {

bodyElt.addEventListener(“unload”, unload_handler, false);

}

} else {

window.onunload=unload_handler;

}

}

18 Comments to “unload Events in Safari”

  1. I want to say thanks for this tip on supporting unload in 1.3. We are building a complex site that requires this call to manage content for us and this was the only workaround out there that worked.

    One thing to note about Safari and this workaround. You must NOT have an unload attribute attached to the body already or this will block the event handling. I had unload defined from my previous code and it took a bit of testing to figure out this was the blocking code. It appears that the attributes override any event listening… this may be old news to everyone, but was new to me. Thanks again!

    J.

    By James Polanco on August 27th, 2005 at 1:16 pm
  2. Matt, I realize this is a while back; but did you resolve this?

    I am using, for example: window.addEventListener(“unload”, rununload, false)
    with no problem with Safari/1.3.2, Opera/8.5, Nav/7.2 in Mac; they all run the unload function just fine; and it runs a few registered functions.

    It’s possible that something in the unload function, itself (or one it calls) is preventing full execution. –Fran

    By Fran Corpier on February 21st, 2006 at 6:30 pm
  3. What is the link to the page where you use the event?

    By John Fargo on March 16th, 2006 at 9:12 am
  4. Hi, onUnload event is not firing in all versions of Safari browser. I tried with different ways to capture that event like this way as you provided above, but i failed to capture that event. So please help me on this, give suggestions to capture that event. Or any other event is firing when window is closing. Actually, i need to execute when window is closing. But in Safari the window is closing without firing of any events.
    There is any other similar event is firing in safari when window is closing. pleas give suggestion to me, it is urgent. Thanx.

    By Jagadeesh on May 16th, 2006 at 5:56 am
  5. have you actually gotten the frameset unload to work using the AddEventListener?

    I’m trying on both safari 2 and 1.3 and it fails. I get the frameset object and add the event listener, but it never fires.

    (the event listener with the body object works perfectly)

    By mark on January 18th, 2007 at 5:41 pm
  6. Thanks for this post. But, this is not working in Safari 2.0.4. I have tried the following options:
    1. – This is not working in Safari. But this works in IE and FireFox
    2.
    function load()

    {

    if (navigator.userAgent.toLowerCase().indexOf(“safari”)!=-1)

    {

    var bodyElt;

    bodyElt = document.getElementById(“EIBody”);

    if (!bodyElt)

    {

    bodyElt = document.getElementsByTagName(“body”)[0];

    }

    if (bodyElt)

    {

    bodyElt.addEventListener(“unload”, testFunction, false);

    }

    }

    else

    {

    window.onunload=testFunction;

    }

    }

    None of them worked out so far. Any other alternatives? Please help

    Daniel

    By Daniel on February 23rd, 2007 at 4:39 am
  7. That really good thanks a lot for this post. Is there a way to make the difference between a user who reloads the webpage and a user who closes the browser?
    In both cases, the function unload_handler() is called but I was not able to found out a solution using window.opener.closed or window.opener.location.reload(true) …
    Any ideas ?
    please answer to

    By Florent on June 11th, 2007 at 9:26 am
  8. not working.

    By ahlongxp on September 4th, 2007 at 7:28 am
  9. Great post! works for IE & Firefox even with the close button.
    Thanks!

    By Darío Carpio on February 18th, 2008 at 9:30 am
  10. I need to really thank u great post ,this was one of my requirements

    By surendar on May 15th, 2008 at 2:06 am
  11. It’s useful for me! Thanks!

    By michael on November 18th, 2008 at 9:38 pm
  12. hi,
    i am using addEventListener() function to initiate my other function but this is working on all browswre except safari on MAC ..

    help will be appriciated.
    thanks,
    puneet

    By Puneet on March 10th, 2009 at 4:40 pm
  13. It’s realy good post. but in my application I want to logout a user automatically on window close.

    I used window.onunload that is working fine with IE. but in Safari 4.0.4 this event gets called while I refresh the page but not on click of ‘X’ button.
    please suggest any solution
    Thanks

    By Abha on January 21st, 2010 at 6:39 am
  14. Hi,
    I took a approach to get around a lot of code. We have Shareable Content Objects used by a Learning management server and if they were loaded in a popup window, running in a IFRAME, Object or Frameset they never got the message to unload. So I just added:
    parent.window.onunload = exitSCO; // attempt to get around LMS popupwindow
    parent.window.onbeforeunload = exitSCO; // attempt to get around LMS popupwindow
    window.onbeforeunload = exitSCO;
    window.onunload = exitSCO;

    Untested in IE, but Safari, FireFox, Chrome ok with it on OSX.

    By Mark on July 8th, 2010 at 4:08 pm
  15. Here’s a code that works for me in 4 browsers (IE,FF,Safari,Chrome) – the unload event is fired all the time.

    —- whichever browser detection method you use
    if(/*browser is Internet Explorer*/)
    window.onunload = unload_event;
    else
    window.addEventListener(‘unload’,unload_event,false);

    By Wizard on August 3rd, 2011 at 11:41 am
  16. About the above comment, actually it’s onbeforeunload.

    if(/*browser is Internet Explorer*/)
    window.onbeforeunload = unload_event;
    else
    window.addEventListener(‘beforeunload’,unload_event,false);

    By Wizard on August 3rd, 2011 at 12:11 pm
  17. the onbeforeunload doesnt seem to be working with the safari running on iPhone and iPad etc. Any help on how do i capture browser close , page refresh , clicking on external link in mobile safari?

    Thanks in Advance
    Hariprasath

    By Hariprasath Mohankumar on October 20th, 2011 at 5:50 am
  18. I love the new Safari 4, and I hope it gets a ‘Recently Closed Tabs’ ferutae (similar to Firefox) instead of just a History menu (which I find pretty much useless – when you click on one of the entries they open in your current tab/window).The new tab / new window issue also bugged me, but given that Safari 4 is still in Beta I hope they’ll fix this in the final release.

    By Jaiho on February 12th, 2012 at 1:52 am

Leave a Reply