我想检查当前浏览器是否支持onbeforeunload事件.执行此操作的常见JavaScript方法似乎不起作用:
if (window.onbeforeunload) {
alert('yes');
}
else {
alert('no');
}
Run Code Online (Sandbox Code Playgroud)
实际上,它只检查某个处理程序是否已附加到事件.有没有办法检测是否支持onbeforeunload而不检测特定的浏览器名称?
不幸的是,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);
Run Code Online (Sandbox Code Playgroud)
这是一个完整的jsfiddle与示例用法.
请注意,它只会在您网站上的第二个或任何后续页面加载中检测到.如果让它在第一页上工作很重要,你可以iframe
在该页面上加载一个src
属性,该属性指向同一域上的页面,并在此处进行检测,确保已加载然后将其删除.这应该确保已经完成检测,因此isBeforeunloadSupported()
即使在第一页也能正常工作.但我不需要那样,所以我没有把它放在我的演示中.
小智 6
我意识到我在这方面有点迟了,但我现在正在处理这个问题,而且我认为更像下面这样的东西会更容易,更可靠.这是jQuery特定的,但它应该适用于任何允许您绑定和取消绑定事件的系统.
$(window).bind('unload', function(){
alert('unload event');
});
window.onbeforeunload = function(){
$(window).unbind('unload');
return 'beforeunload event';
}
Run Code Online (Sandbox Code Playgroud)
unload
如果beforeunload
事件触发,这应该取消绑定事件.否则它将简单地解除卸载.