有没有办法在 iOS 设备的 Mobile Safari 上使用 window.onbeforeunload ?

发布于 2024-09-30 20:34:18 字数 213 浏览 4 评论 0原文

看起来 Apple 已禁用 iOS 设备(iPhone、iPad、iPod Touch)的 window.onbeforeunload 事件。不幸的是,我找不到任何文档来说明为什么此事件在 Mobile Safari 中不起作用。

有谁知道这个功能是否有可靠的替代方案? Android 的浏览器似乎支持得很好,Safari 桌面应用程序也支持 onbeforeunload 事件,没有任何问题。

Looks like Apple has disabled the window.onbeforeunload event for iOS devices (iPhone, iPad, iPod Touch). Unfortunately I can't find any documentation as to why this event doesn't work in Mobile Safari.

Does anyone know if there's a reliable alternative to this function? Android's browser appears to support it just fine, and the Safari desktop application also supports the onbeforeunload event without issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最美的太阳 2024-10-07 20:34:18

我发现这是一个老问题,但我最近遇到了这个问题。

我正在使用 window.unload 并且它在 ios 浏览器中运行良好(尽管如果您查看 Apple 文档 似乎已弃用,他们建议使用 window.pagehide

I see that it's an old question, but i faced this problem recently.

I'm using window.unload and it works fine in ios browsers (although if you look at Apple documentation it seems to be deprecated and they recommend to use window.pagehide)

蓝天白云 2024-10-07 20:34:18

如果你确实需要它,你不能只获取所有具有更改 url 的处理程序的链接、表单和 DOM 对象,并让它们等待,直到你完成你想要的操作。
对于链接,您可以通过 getElementsByTagName 获取它们,检查 href 是否以 # 以外的任何内容开头,然后添加 onbeforeunload 函数 add onclick (该函数将在查看 href 之前调用)。
表单相同,但带有 onsubmit。
最后,对于使用 JavaScript 更改 href 的元素,您应该确保在添加 lsitener 时调用 onbeforeunlaod 函数(或者,如果您使用 DOM0 或 DOM1 侦听器,则只需添加一些类,然后使用全局脚本检查该类的所有元素并将其添加到带有闭包的事件侦听器中,

但是您通常应该能够避免使用此事件(可能使用 cookie 来存储您想要每 x 秒发送的内容并允许,在最坏的情况下,下次用户加载页面时查看它,在最好的情况下,能够在 onbeforeunload 或 onunload 处发送 Ajax 请求,即使它只发送 http 标头,也将允许您得到你想要的)。

If you really need it, you cant just get all links, forms and DOM objects that have a handler changing the url and make those wait until you've done what you want.
For the links, you get them by getElementsByTagName, check if the href starts with anything but a # and just add your onbeforeunload function add onclick (which will be invoked before the href is looked at).
Same for the forms but with onsubmit.
And finaly, for the elements changing the href with JavaScript, you should make sure when you add the lsitener that you call your onbeforeunlaod function (or, if you use DOM0 or DOM1 listeners, you can just add some class and then use a global script that checks all elements with the class and adds it to the event listener with a closure.

But you should normaly be able to avoid the use of this event (probably using cookies to store the thing you wanted to send every x seconds and allowing to, in the worst case, have a look at it next time the user loads a page and, in the best case, be able to send an Ajax request at onbeforeunload or onunload which, even if it sends only the http headers, woudl allow you to get what you want).

初懵 2024-10-07 20:34:18

根据泽维尔的回答,我设计了一个解决方案:

function doStuff() {
  // here goes your logic
}

function isSafariMobile() {
  return navigator && /Safari/.test(navigator.userAgent) && /iPhone|iPad/.test(navigator.userAgent)
}

function addWatcherToLinks(baseNode) {
  if (!baseNode || !baseNode.querySelectorAll) { return; } // ignore comments, text, etc.
  for (const link of baseNode.querySelectorAll("a")) {
    link.addEventListener('click', doStuff);
  }
  for (const form of baseNode.querySelectorAll("form")) {
    form.addEventListener('submit', doStuff);
  }
}

// ...when the page loads...
// we watch the page for beforeunload to call doStuff
// Since Safari mobile does not support this, we attach a listener (watcher) to each link and form and then call doStuff.
// Also, we add such a watcher to all new incoming nodes (DOMNodeInserted).
if (isSafariMobile()) {
  addWatcherToLinks(document);
  window.addEventListener("DOMNodeInserted", (event) => { addWatcherToLinks(event.target); }, false);
} else {
  window.addEventListener('beforeunload', doStuff);
}

该解决方案有一些限制。最大的一个是它附加到所有表单和所有链接。有时这可能不是所希望的。如果您需要它,您可以跳过一些节点(例如,使用特定的 data- 属性标记它们)。

Based on Xavier's answer, I devised a solution along these lines:

function doStuff() {
  // here goes your logic
}

function isSafariMobile() {
  return navigator && /Safari/.test(navigator.userAgent) && /iPhone|iPad/.test(navigator.userAgent)
}

function addWatcherToLinks(baseNode) {
  if (!baseNode || !baseNode.querySelectorAll) { return; } // ignore comments, text, etc.
  for (const link of baseNode.querySelectorAll("a")) {
    link.addEventListener('click', doStuff);
  }
  for (const form of baseNode.querySelectorAll("form")) {
    form.addEventListener('submit', doStuff);
  }
}

// ...when the page loads...
// we watch the page for beforeunload to call doStuff
// Since Safari mobile does not support this, we attach a listener (watcher) to each link and form and then call doStuff.
// Also, we add such a watcher to all new incoming nodes (DOMNodeInserted).
if (isSafariMobile()) {
  addWatcherToLinks(document);
  window.addEventListener("DOMNodeInserted", (event) => { addWatcherToLinks(event.target); }, false);
} else {
  window.addEventListener('beforeunload', doStuff);
}

This solution has some limitations. The biggest one is that it attaches itself to all forms and all links. Sometimes this might not be desired. If you need it you can skip some nodes (e.g. mark them with a particular data- attribute).

晌融 2024-10-07 20:34:18

我也遇到了同样的问题。似乎 iPhone 中的 Safari 浏览器仅触发焦点和模糊事件,几乎所有其他事件都不会触发,例如(页面隐藏、页面显示、可见性更改),但好消息是焦点和模糊事件在 iphone、ipad 和 iphone 上都受支持和触发。安卓手机也是如此。

    window.addEventListener('focus', function(){
       // do stuff
     });

   window.addEventListener('blur', function(){
       // do stuff
     });

希望这对任何人都有帮助。

I was having the same problem. it seems safari browser in iphone triggers only focus and blur events and almost every other event is not triggered, e.g.(pagehide, pageshow, visibility change) but the good news is focus and blur event are supported and triggered on iphone, ipad & android mobiles as well.

    window.addEventListener('focus', function(){
       // do stuff
     });

   window.addEventListener('blur', function(){
       // do stuff
     });

hope this helps anyone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文