92

Does anyone know if the onbeforeunload event is supported on the iPad and/or if there's a different way to use it?

I've tried pretty much everything, and it seems like the onbeforeunload event is never triggered on the iPad (Safari browser).

Specifically, this is what I've tried:

  • window.onbeforeunload = function(event) { event.returnValue = 'test'; }
  • window.onbeforeunload = function(event) { return 'test'; }
  • (both of the above together)
  • window.onbeforeunload = function(event) { alert('test')'; }
  • (all of the above functions but inside <body onbeforeunload="...">

All of these work on FF and Safari on the PC, but not on the iPad.

Also, I've done the following just after loading the page:

alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);

Respectively, the results are:

  • true
  • object
  • null

So, the browser does have the property, but for some reason it doesn't get fired.

The ways I try to navigate away from the page are by clicking the back and forward buttons, by doing a google search in the top bar, by changing location in the address bar, and by clicking on a bookmark.

Does anyone have any idea about what's going on? I'd greatly appreciate any input.

Thanks

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Art Zambrano
  • 929
  • 1
  • 7
  • 4
  • Thank you both for your input. It must be one of the reasons you mentioned. Unfortunately, there's no official documentation from Apple regarding this and other limitations. Hopefully, they will come up with a more creative way of enabling this feature, while preventing malicious use of it. I hear very often that people accidentally tap away from the page and lose all the data they had entered in a form. – Art Zambrano Jul 16 '10 at 17:15
  • Have you tried using `addEventListener()`? – Hello71 Jan 28 '11 at 02:52
  • 2
    I'm pretty sure `beforeunload` doesn't work on Safari on iOS. :-( Perhaps not what you're looking for, but I have a suggestion for how to [reliably test for a working `beforeunload`](http://stackoverflow.com/a/18137334/345716) – Peter V. Mørch Aug 08 '13 at 22:36
  • 1
    On Mar 3'16, The ```window.onbeforeunload = function(event) { event.returnValue = 'test'; }``` doesn't work on both Chrome and Safari of iOS 9.2.1 . I really like ```onbeforeunload``` Because the page does not change if I click cancel. – vanduc1102 Mar 01 '16 at 09:05
  • Seems like this problem was solved in Safari and iOS 13 – Finesse Oct 18 '19 at 14:25
  • @Finesse, I just tested it on Safari with iOS 15, and the problem is still present. – Ben Wheeler Jul 12 '22 at 14:25

8 Answers8

27

This bit of JavaScript works for me on Safari and Chrome on ipad and iphone, as well as desktop/laptop/other browsers:

var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";

window.addEventListener(eventName, function (event) { 
    window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
    ...
} );
Danger
  • 2,043
  • 2
  • 21
  • 24
  • 1
    It can catch the event, but how can you pop up the confirmation prompt? Using `return 'test';` similar to that by op isn't working.. – user2335065 Jul 05 '15 at 16:33
  • Thanks I missed that in the original question. I haven't specifically tested this on iOS, but possibly adding this additional line would work: window.event.cancelBubble = true; I'll add to my answer – Danger Jul 07 '15 at 19:59
  • 3
    Thanks, but sadly it does not work... I tried to put alert() inside it, seems the new page has begun to load before the alert() is fired. Also see this: http://stackoverflow.com/questions/3239834/window-onbeforeunload-not-working-on-the-ipad – user2335065 Jul 08 '15 at 02:26
  • @user2335065 did you find any solution for the same. – Neeraj Rathod Sep 10 '17 at 06:29
  • 1
    guys, did you find any solution to show the confirmation prompt before leaving page? This works fine in every browser except IOS safari. I tried pagehide event too, but didn't work for me. Thanks in advance. – Rahul Sep 06 '19 at 08:51
  • 1
    I've tested multiple workarounds and I'm pretty sure it's not possible to show the confirmation prompt when on iOS, regardless of the browser used. – fnagel Nov 09 '21 at 15:19
  • var eventName = !!isOnIOS ? "pagehide" : "beforeunload" to avoid always TRUE – Shawn Wu Aug 24 '22 at 10:05
20

I have found that the onunload() event does fire. It's behavior is somewhat odd; whatever you have in your callback function attached to the event is actually run after the new page has loaded in the background (You can't tell it's loaded yet, but server logging will show that it has).

More oddly, if you have a confirm() call in your onunload(), and the user has clicked a link to go somewhere else, you are in business. If, however, the user closes the iPad Safari browser tab, the onunload() event will fire, but your confirm() will have an implicit cancel as response.

Danny Armstrong
  • 1,320
  • 12
  • 13
  • Huh, seems this confirm quirk (that the second page is hit before the confirm message) is true not just for mobile safari but for firefox (and probably others) as well. You just blew my mind. – Alkanshel Aug 03 '11 at 23:59
  • 6
    `unload` event deprecated in favor of `pagehide` see https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW5 – sol0mka Jun 09 '16 at 13:58
  • 1
    @sol0mka: That’s it, man! Great! In my case the following code did the job, so far as I can see for all my browsers AND iOS: $(window).on('beforeunload pagehide', function() { // my stuff that has to be done on page change } ); This should be the accepted answer in my eyes. – Garavani Dec 16 '16 at 15:25
  • It shoud be noted that, under certain conditions, the unload, beforeunload and pagehide events may not fire reliably by the browser. For example, pagehide will not fire if a mobile user closes the browser app via the app manager. Source: https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event – Nadav Jul 15 '21 at 02:14
6

Only Apple would know for sure, but my guess is that they purposely did not enable that functionality in mobile Safari because it is most often used by shady characters to get you to stay on their site or pop up lots of porn/advertising windows.

Charles Boyung
  • 2,464
  • 1
  • 21
  • 31
  • 63
    Or, you know, save your changes automatically so they aren't lost just because you accidentally tapped the wrong thing. – Joel Mueller Jul 14 '10 at 17:38
  • 5
    I didn't say there weren't valid uses, I just said that those were the most often uses. – Charles Boyung Jul 14 '10 at 18:38
  • 3
    @JoelMueller Your comment should be the accepted answer :) – sanchez Apr 22 '14 at 13:30
  • 1
    @JoelMueller That is exactly my use case. Grrr @ apple – user2808054 Apr 14 '16 at 14:00
  • @JoelMueller can you please share any official doc where we can address this statement that mobile safari saves changes automatically. – Neeraj Rathod Sep 10 '17 at 06:53
  • If that's why they don't support "beforeunload" what do you suppose their reason for supporting "pagehide" is? Maybe they're invested in StackOverflow and just wanted to force more people onto this site to figure this out... – ChrisFox Feb 20 '20 at 13:24
  • @NeerajRathod probably too late but what he meant was window.onbeforeunload can be used to save changes automatically if user accidentally closed the tab and you got it wrong – void Jul 07 '21 at 12:39
3

beforeunload event is not supported by Mobile Safari. You can see the list of all supported events here: Handling Events Apple documentation

And the beforeunload is not in the list!

Julien Bachmann
  • 753
  • 8
  • 18
3

There's a known bug in WebKit with onbeforeunload. I believe it's fixed in the latest beta of Chrome 5, but it's quite possible the iPad's browser is made from a version of WebKit that doesn't have the fix.

Related Chrome bug report.

Joel Mueller
  • 28,324
  • 9
  • 63
  • 88
2

https://code.google.com/p/chromium/issues/detail?id=97035

see hear.

alerts are no longer allowed during page dismissal events (beforeunload, unload, pagehide).

I think alerts, prompt, confirm, and other actions like these are also no longer allowed.

zelda.j
  • 67
  • 6
2

Here's a solution that should work on all modern browsers:

var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
    if (unloaded)
        return;
    unloaded = true;
    console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
    if (document.visibilityState == 'hidden')
    {
        if (unloaded)
            return;
        unloaded = true;
        console.log("beforeUnload");
    }
});

Mobile browsers don't tend to not support beforeunload because the browser can go into the background without unloading the page, then be killed by the operating system at any time.

Most desktop browser contain a bug that causes visibilityState to not get called when the document unloads. See: here.

Therefore, it's important to include both events to cover all scenarios.

NB

I have used console.log instead of alert in my example because alert will get blocked by some browsers when called from beforeunload or visibilitychange.

Dan Bray
  • 7,242
  • 3
  • 52
  • 70
1

If you just need to know if the page has been left you can use document.unload. It works fine in ios browsers. If you see on Apple documentation you'll find that it's deprecated and they recommend to use document.pagehide

Miquel
  • 8,339
  • 11
  • 59
  • 82