onbeforeunload支持检测

我想检查当前的浏览器是否支持onbeforeunload事件。 常见的JavaScript方式做到这一点似乎不工作:

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

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

我之前曾经写过关于在现代浏览器中检测事件支持的或多或less可靠的推论 。 您可以在演示页面上看到至lessSafari 4+,FF3.x +和IE支持“beforeunload”。

编辑 :这种技术现在用在jQuery,Prototype.js,Modernizr和其他可能的脚本和库。

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

相反,我build议一个不同的方法:

这个想法很简单。 在第一次访问页面时,我们实际上并不知道是否支持beforeunload 。 但是在第一页上,我们设置了一个unload和一个beforeunload处理程序。 如果beforeunload处理程序触发,我们设置一个标志,说明beforeunload支持(其实beforeunloadSupported = "yes" )。 当unload处理程序触发时,如果标志没有被设置,我们设置支持beforeunload的标志。

在下面我们将使用localStorage (在我关心的所有浏览器中都支持 – 请参阅http://caniuse.com/namevalue-storage )获取/设置标志。 我们也可以使用cookie,但是我select了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属性的iframe ,这个属性指向同一个域的一个页面,并且检测到这个页面,确保它已经加载,然后删除它。 这应该确保已经完成检测,因此isBeforeunloadSupported()即使在第一页也能正常工作。 但是我不需要,所以我没有把它放在我的演示中。

我意识到这一点我已经有点迟了,但现在我正在处理这个问题,而且我正在考虑更类似于下面的内容会更容易,更可靠。 这是特定于jQuery,但它应该与任何允许绑定和解除绑定事件的系统一起工作。

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

如果beforeunload事件触发,这应该解除unload事件。 否则,它会简单地解除卸载。

 alert('onbeforeunload' in window); 

如果onbeforeunloadwindow一个属性(即使它是null),警报'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 ,所以这个工作。

Cruster,

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

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

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

希望这些信息有助于一些

不同的方法,获得types

 if(typeof window.onbeforeunload == 'function') { alert("hello functionality!"); } 

onbeforeunload也支持FF,所以testing浏览器不会有帮助。

我发现这是一个非常古老的线程,但是接受的答案错误地检测到了在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和Safari 7.1 for iOS上testing

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

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

…等等。

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