Onbefore 卸载不能在 iPad 上工作?

有没有人知道 iPad 是否支持 onbeforeunload活动,或者是否有不同的使用方式?

我已经尝试了几乎所有的方法,似乎在 iPad (Safari 浏览器)上 onbeforeunload事件永远不会被触发。

具体来说,这就是我所尝试的:

  • window.onbeforeunload = function(event) { event.returnValue = 'test'; }
  • window.onbeforeunload = function(event) { return 'test'; }
  • (以上两者合计)
  • window.onbeforeunload = function(event) { alert('test')'; }
  • (除 <body onbeforeunload="...">以外的所有上述函数

所有这些都可以在 PC 上的 FF 和 Safari 上运行,但是在 iPad 上不能。

另外,我在加载页面之后做了以下工作:

alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);

结果如下:

  • true
  • object
  • null

所以,浏览器确实有这个属性,但是由于某种原因它没有被激活。

我尝试从页面导航离开的方式是通过点击后退和前进按钮,通过在顶部栏进行谷歌搜索,通过改变地址栏中的位置,并通过点击书签。

有人知道发生了什么事吗? 我非常感谢你们的意见。

谢谢

61042 次浏览

Only Apple would know for sure, but my guess is that they purposely did not enable that functionality in mobile Safari because it is most often used by shady characters to get you to stay on their site or pop up lots of porn/advertising windows.

There's a known bug in WebKit with onbeforeunload. I believe it's fixed in the latest beta of Chrome 5, but it's quite possible the iPad's browser is made from a version of WebKit that doesn't have the fix.

Related Chrome bug report.

I have found that the onunload() event does fire. It's behavior is somewhat odd; whatever you have in your callback function attached to the event is actually run after the new page has loaded in the background (You can't tell it's loaded yet, but server logging will show that it has).

More oddly, if you have a confirm() call in your onunload(), and the user has clicked a link to go somewhere else, you are in business. If, however, the user closes the iPad Safari browser tab, the onunload() event will fire, but your confirm() will have an implicit cancel as response.

If you just need to know if the page has been left you can use document.unload. It works fine in ios browsers. If you see on Apple documentation you'll find that it's deprecated and they recommend to use document.pagehide

https://code.google.com/p/chromium/issues/detail?id=97035

see hear.

alerts are no longer allowed during page dismissal events (beforeunload, unload, pagehide).

I think alerts, prompt, confirm, and other actions like these are also no longer allowed.

beforeunload event is not supported by Mobile Safari. You can see the list of all supported events here: Handling Events Apple documentation

And the beforeunload is not in the list!

This bit of JavaScript works for me on Safari and Chrome on ipad and iphone, as well as desktop/laptop/other browsers:

var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";


window.addEventListener(eventName, function (event) {
window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
...
} );

Here's a solution that should work on all modern browsers:

var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
if (document.visibilityState == 'hidden')
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
}
});

Mobile browsers don't tend to not support beforeunload because the browser can go into the background without unloading the page, then be killed by the operating system at any time.

Most desktop browser contain a bug that causes visibilityState to not get called when the document unloads. See: here.

Therefore, it's important to include both events to cover all scenarios.

NB

I have used console.log instead of alert in my example because alert will get blocked by some browsers when called from beforeunload or visibilitychange.