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);
如果onbeforeunload
是window
一个属性(即使它是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的实现。