我想检查当前浏览器是否支持onbeforeunload事件。 这种常见的javascript方式似乎不起作用:
if (window.onbeforeunload) {
alert('yes');
}
else {
alert('no');
}
实际上,它只检查某个处理程序是否已附加到该事件。 有没有办法检测是否支持onbeforeunload而不检测特定的浏览器名称?
答案 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
。但是在第一页上,我们设置了一个
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()
即使在第一页也能正常工作。但我不需要那样,所以我没有把它放在我的演示中。
答案 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);
如果onbeforeunload
是window
的属性(即使它为空),则警告'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)
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对这些函数的实现。