onbeforeunload 支持检测

IT技术 javascript
2021-03-09 18:05:32

我想检查当前浏览器是否支持 onbeforeunload 事件。执行此操作的常见 javascript 方法似乎不起作用:

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

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

6个回答

前段时间我写了一篇关于在现代浏览器中检测事件支持的或多或少可靠的推理您可以在演示页面上看到至少 Safari 4+、FF3.x+ 和 IE 支持“beforeunload”。

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

警告:我在@kangax 的页面上写了一条评论,专门关于onbeforeunload在 Mobile Safari 上被检测为支持,即使它实际上不能可靠地工作
2021-05-03 18:05:32
链接到上面的站点是向下的吗?对我不起作用,但我找到了缓存版本
2021-05-09 18:05:32

不幸的是,kangax 的答案不适用于iOS 上的 Safari在我的测试beforeunload中,我尝试过的每个浏览器都支持,除了 IOS 上的 Safari :-(

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

这个想法很简单。在第一次访问页面时,我们实际上还不知道是否 beforeunload支持。但是在第一页上,我们设置了一个 unload和一个beforeunload处理程序。如果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()即使在第一页也能正常工作。但我不需要它,所以我没有把它放在我的演示中。

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

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

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

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

alert('onbeforeunload' in window);

如果onbeforeunload是 的属性window(即使它为空),则警告“真”

这应该做同样的事情:

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

最后:

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

同样,typeof window.onbeforeunload即使它当前具有 value null它似乎也是 'object' ,所以这是有效的。

这在 iOS Safari 中对我不起作用。即使不支持,它也会说支持 beforeunload 事件
2021-04-16 18:05:32
在 IE、Opera 和 Safari 中几乎可以正常工作,但 FF 给我错误,这似乎不正确
2021-04-21 18:05:32
Firefox 不支持这种推断,但允许检测“beforeunload”是否在元素上设置相应的属性。var el = document.createElement('div'); el.setAttribute('onbeforeunload', ''); typeof el.onbeforeunload; // “功能”
2021-05-05 18:05:32
抱歉,我认为它运行可靠,因为我没有意识到 Firefox onbeforeunload 支持。
2021-05-06 18:05:32

结壳,

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

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

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

希望这些信息对一些人有帮助

谢谢伙计,但这只是理论 - 请参阅此问题的其他答案,您会找到几乎完美的解决方案。所以,我真的不在乎 DOM 是否提供一些接口。实际上,有可靠的方法来检查它,这很重要。哦,顺便说一句,只有 Opera 缺乏支持。
2021-04-28 18:05:32