onbeforeunload support detection

前端 未结 10 1074
慢半拍i
慢半拍i 2020-11-28 11:21

I\'d like to check if the current browser supports the onbeforeunload event. The common javascript way to do this does not seem to work:

if (window.onbeforeu         


        
相关标签:
10条回答
  • 2020-11-28 11:38

    I wrote about a more-or-less reliable inference for detecting event support in modern browsers some time ago. You can see on a demo page that "beforeunload" is supported in at least Safari 4+, FF3.x+ and IE.

    Edit: This technique is now used in jQuery, Prototype.js, Modernizr, and likely other scripts and libraries.

    0 讨论(0)
  • 2020-11-28 11:40

    I see that this is a very old thread, but the accepted answer incorrectly detects support for Safari on iOS, which caused me to investigate other strategies:

    if ('onbeforeunload' in window && typeof window['onbeforeunload'] === 'function') {
      // onbeforeunload is supported
    } else {
      // maybe bind to unload as a last resort
    }
    

    The second part of the if-check is necessary for Safari on iOS, which has the property set to null.

    Tested in Chrome 37, IE11, Firefox 32 and Safari for iOS 7.1

    0 讨论(0)
  • 2020-11-28 11:41

    Cruster,

    The "beforeunload" is not defined in the DOM-Events specification, this is a IE-specific feature. I think it was created in order to enable execution to be triggered before standard "unload" event. In other then IE browsers you could make use of capture-phase "unload" event listener thus getting code executed before for example an inline body onunload event.

    Also, DOM doesn't offer any interfaces to test its support for a specific event, you can only test for support of an events group (MouseEvents, MutationEvents etc.)

    Meanwhile you can also refer to DOM-Events specification http://www.w3.org/TR/DOM-Level-3-Events/events.html (unfortunately not supported in IE)

    Hope this information helps some

    0 讨论(0)
  • 2020-11-28 11:42
    alert('onbeforeunload' in window);
    

    Alerts 'true' if onbeforeunload is a property of window (even if it is null).

    This should do the same thing:

    var supportsOnbeforeunload = false;
    for (var prop in window) {
        if (prop === 'onbeforeunload') {
        supportsOnbeforeunload = true;
        break;
        }
    }
    alert(supportsOnbeforeunload);
    

    Lastly:

    alert(typeof window.onbeforeunload != 'undefined');
    

    Again, typeof window.onbeforeunload appears to be 'object', even if it currently has the value null, so this works.

    0 讨论(0)
  • 2020-11-28 11:43

    Unfortunately kangax's answer doesn't work for Safari on iOS. In my testing beforeunload was supported in every browser I tried exactly except Safari on IOS :-(

    Instead I suggest a different approach:

    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 no reason to send this information to the web server at every request. We just need a flag that survives page reloads. Once we've detected it once, it'll stay detected forever.

    With this, you can now call isBeforeunloadSupported() and it will tell you.

    (function($) {
        var field = 'beforeunloadSupported';
        if (window.localStorage &&
            window.localStorage.getItem &&
            window.localStorage.setItem &&
            ! window.localStorage.getItem(field)) {
            $(window).on('beforeunload', function () {
                window.localStorage.setItem(field, 'yes');
            });
            $(window).on('unload', function () {
                // If unload fires, and beforeunload hasn't set the field,
                // then beforeunload didn't fire and is therefore not
                // supported (cough * iPad * cough)
                if (! window.localStorage.getItem(field)) {
                    window.localStorage.setItem(field, 'no');
                }
            });
        }
        window.isBeforeunloadSupported = function () {
            if (window.localStorage &&
                window.localStorage.getItem &&
                window.localStorage.getItem(field) &&
                window.localStorage.getItem(field) == "yes" ) {
                return true;
            } else {
                return false;
            }
        }
    })(jQuery);
    

    Here is a full jsfiddle with example usage.

    Note that it will only have been detected on the second or any subsequent page loads on your site. If it is important to you to have it working on the very first page too, you could load an iframe on that page with a src attribute pointing to a page on the same domain with the detection here, make sure it has loaded and then remove it. That should ensure that the detection has been done so isBeforeunloadSupported() works even on the first page. But I didn't need that so I didn't put that in my demo.

    0 讨论(0)
  • 2020-11-28 11:44

    It would probably be better to just find out by hand which browsers support it and then have your conditional more like:

    if( $.browser.msie ) {
      alert( 'no' );
    }
    

    ...etc.

    The $.browser.msie is jQuery syntax, most frameworks have similar built-in functions since they use them so much internally. If you aren't using a framework then I'd suggest just taking a look at jQuery's implementation of those functions.

    0 讨论(0)
提交回复
热议问题