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

Javascript 有没有办法在iOS设备的Mobile Safari上使用window.onbeforeunload?,javascript,iphone,ios,mobile-safari,onbeforeunload,Javascript,Iphone,Ios,Mobile Safari,Onbeforeunload,看起来苹果已经为iOS设备(iPhone、iPad、iPod Touch)禁用了window.onbeforeunload事件。不幸的是,我找不到任何文档说明为什么这个事件在Mobile Safari中不起作用 有人知道这个功能是否有可靠的替代方案吗?Android浏览器似乎很好地支持它,Safari桌面应用程序也支持onbeforeunload事件,没有问题。如果您真的需要它,您不能只获取所有链接、表单和DOM对象,这些链接、表单和DOM对象都有一个处理程序更改url,并让它们等待您完成所需的

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


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

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


但是您通常应该能够避免使用此事件(可能使用Cookie每隔x秒存储您想要发送的内容,在最坏的情况下,允许用户下次加载页面时查看它,在最好的情况下,能够在onbeforeunload或onunload发送Ajax请求,即使它只发送http头,也可以让您获得所需内容).

我知道这是个老问题,但我最近遇到了这个问题


我使用的是
window.unload
,它在ios浏览器中运行良好(不过如果你看到它似乎不太受欢迎,他们建议使用
document.pagehide

基于Xavier的回答,我设计了一个大致如下的解决方案:

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);
}

此解决方案有一些限制。最大的限制是它将自身附加到所有表单和所有链接。有时可能不需要这样做。如果需要,可以跳过一些节点(例如,使用特定的
数据-
属性标记它们).

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

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

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

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

谢谢Xavier,所有的可能性,但这些都需要大量的DOM修改,这在我的应用程序中是不切实际的,因为它可能会干扰托管页面的功能。您不需要在每个链接上添加事件,等等,您可以使用事件委派。您只需在b上添加一个即可使用e.srcElement | | e.target,然后检查它是否会更改url。这样,您不需要放置那么多元素。但是您可能仍然需要将onsubmit放在表单上自己…对此不确定。对于用户实际关闭页面而不是通过元素移动到另一个页面的场景,有任何选项吗?没有如果是在电脑上,你可以检测到鼠标离开窗口并做好准备。最好是告诉服务器“我还在这里”一直都是这样,这样它就可以推断出你离开了,而你没有离开,所以设置一个服务器超时。使用WebSocket而不是许多Ajax调用可能会更好。除此之外,我唯一能想到的就是总是强迫用户也有一些重点,在onblur发送消息(可能在它之后添加一点true)。无论如何,如果不打扰用户,您将无法使用任何东西。这是的副本。这是否回答了您的问题?当用户重新加载页面时,pagehide和unload似乎都无法在iOS 9上工作。因此…我们应该使用什么?:)