onbeforeunload支持检测

时间:2008-10-01 17:08:29

标签: javascript

我想检查当前浏览器是否支持onbeforeunload事件。 这种常见的javascript方式似乎不起作用:

if (window.onbeforeunload) {
    alert('yes');
}
else {
    alert('no');
}

实际上,它只检查某个处理程序是否已附加到该事件。 有没有办法检测是否支持onbeforeunload而不检测特定的浏览器名称?

10 个答案:

答案 0 :(得分:27)

前段时间我在现代浏览器中写过一个或多或少的reliable inference for detecting event support。您可以在演示页面上看到至少在Safari 4 +,FF3.x +和IE中支持“beforeunload”。

编辑:此技术现在用于jQuery,Prototype.js,Modernizr以及其他脚本和库。

答案 1 :(得分:7)

不幸的是kangax's answer不适用于Safari on iOS。在我的测试中,除了IOS上的Safari之外,我在每个浏览器中都支持beforeunload: - (

相反,我建议采用不同的方法:

这个想法很简单。在第一页访问时,我们实际上还不知道是否 支持beforeunload。但是在第一页上,我们设置了一个 unloadbeforeunload处理程序。如果beforeunload处理程序触发,我们设置一个 标志说支持beforeunload(实际上是beforeunloadSupported = "yes")。当unload处理程序触发时,如果尚未设置标志,我们设置 标记beforeunload 支持。

在下文中,我们将使用localStorage(在我关注的所有浏览器中均受支持 关于 - 请参阅http://caniuse.com/namevalue-storage)获取/设置标志。我们 也可以使用cookie,但我选择了localStorage因为那里 没有理由在每次请求时将此信息发送到Web服务器。我们 只需要一个幸存页面重新加载的标志。一旦我们检测到它一次,它就会 永远被发现。

有了这个,你现在可以打电话给isBeforeunloadSupported(),它会告诉你。

(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);

以下是一个完整的jsfiddle示例用法。

请注意,只有在您网站上的第二次或任何后续网页加载时才会检测到它。如果让它在第一页上工作也很重要,您可以在该页面上加载iframe,其中src属性指向同一域上的页面并在此处进行检测,确保已加载然后将其删除。这应该确保已经完成检测,因此isBeforeunloadSupported()即使在第一页也能正常工作。但我不需要那样,所以我没有把它放在我的演示中。

答案 2 :(得分:6)

我意识到我在这一点上有点迟了,但我现在正在处理这个问题,而且我认为更像以下的东西会更容易,更可靠。这是特定于jQuery的,但它应该适用于任何允许您绑定和取消绑定事件的系统。

$(window).bind('unload', function(){
    alert('unload event');
});

window.onbeforeunload = function(){
    $(window).unbind('unload');
    return 'beforeunload event';
}

如果unload事件触发,则应取消beforeunload事件的绑定。否则它只会解除卸载。

答案 3 :(得分:2)

alert('onbeforeunload' in window);

如果onbeforeunloadwindow的属性(即使它为空),则警告'true'。

这应该做同样的事情:

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

最后:

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

同样,typeof window.onbeforeunload似乎是'对象',即使它当前的值为null,所以这也有效。

答案 4 :(得分:2)

Cruster,

DOM-Events规范中未定义“beforeunload”,这是IE特有的功能。我认为它是为了在标准的“卸载”事件之前触发执行而创建的。在其他IE浏览器中,您可以使用捕获阶段“卸载”事件侦听器,从而在执行代码之前执行代码,例如内联正文onunload事件。

此外, DOM不提供任何接口来测试其对特定事件的支持,您只能测试事件组的支持(MouseEvents,MutationEvents等)。

同时你也可以参考DOM-Events规范http://www.w3.org/TR/DOM-Level-3-Events/events.html(遗憾的是IE不支持)

希望这些信息有所帮助

答案 5 :(得分:0)

不同的方法,获取类型

if(typeof window.onbeforeunload == 'function')

{
alert("hello functionality!");
}

答案 6 :(得分:0)

FF也支持

onbeforeunload,因此测试浏览器无济于事。

答案 7 :(得分:0)

移动浏览器通常不支持beforeunload,因为浏览器可以在不卸载页面的情况下进入后台,然后随时被操作系统杀死。

但是,所有现代的非移动浏览器都支持它。因此,您只需检查浏览器是否为移动浏览器即可。

要解决此问题,我使用:

var isMobile = navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/iPhone|iPad|iPod/i) || navigator.userAgent.match(/Opera Mini/i) || navigator.userAgent.match(/IEMobile/i);
if (isMobile)
{
    window.addEventListener("visibilitychange", function(e)
    {
        if (document.visibilityState == 'hidden')
        {
            console.log("beforeunload");
            location.reload();
        }
    });
}
else
{
    window.addEventListener("beforeunload", function(e)
    {
        console.log("beforeunload");
    });
}

答案 8 :(得分:-1)

我发现这是一个非常老的线程,但是接受的答案错误地检测到iOS上对Safari的支持,这导致我调查其他策略:

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

iOS上的Safari需要if-check的第二部分,其属性设置为null

在Chrome 37,IE11,Firefox 32和适用于iOS 7.1的Safari中测试

答案 9 :(得分:-4)

最好是手动找出哪些浏览器支持它,然后让你的条件更像:

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

...等

$.browser.msie是jQuery语法,大多数框架都有类似的内置函数,因为它们在内部使用它们非常多。如果您没有使用框架,那么我建议您只看一下jQuery对这些函数的实现。