在窗口关闭或页面刷新时运行 JavaScript 代码?

IT技术 javascript browser
2021-01-29 01:47:13

当用户关闭浏览器窗口或刷新页面时,有没有办法运行最终的 JavaScript 代码?

我在想类似于 onload 但更像 onclose 的东西?谢谢。

我不喜欢 onbeforeunload 方法,它总是会弹出一个确认框(离开页面/留在 mozilla 上)或(重新加载/不要在 chrome 上重新加载)。有没有办法安静地执行代码?

6个回答

window.onbeforeunloadwindow.onunload,根据浏览器的不同使用方式不同。您可以通过将窗口属性设置为函数或使用以下命令来分配它们.addEventListener

window.onbeforeunload = function(){
   // Do something
}
// OR
window.addEventListener("beforeunload", function(e){
   // Do something
}, false);
   

通常,onbeforeunload用于阻止用户离开页面(例如,用户正在处理一些未保存的数据,因此他/她应该在离开前保存)。Operaonunload不支持,据我所知,但你总是可以同时设置。

我知道这是一个可接受的答案,但是当我在 //DO SOMETHING 中添加警报时,它不会发送警报消息。这是正常的吗?因为我觉得它在我关闭或刷新时都没有运行该警报。
2021-03-17 01:47:13
这对我有用:Firefox (69.0.2) 和 Chrome (77.0.3865.90)
2021-03-19 01:47:13

好的,我为此找到了一个可行的解决方案,它包括使用beforeunload事件然后使处理程序返回null这将执行所需的代码,而不会弹出确认框。它是这样的:

window.onbeforeunload = closingCode;
function closingCode(){
   // do something...
   return null;
}
这不是在导航和刷新 (F5) 时也被触发吗?如果是这样,它并没有真正解决问题......
2021-03-25 01:47:13
return false 仍然会弹出对话框询问是否要离开该页面。我在锚上对其进行了测试。返回 null 对话框没有弹出,但它仍然执行了 console.log
2021-04-02 01:47:13
未经测试,但我认为return false;这样做是一样的(即防止默认行为),并且在语义上更正确。
2021-04-07 01:47:13

有时您可能想让服务器知道用户正在离开页面。这很有用,例如,清理临时存储在服务器上的未保存图像、将该用户标记为“离线”或在他们完成会话后进行记录。

过去,您会在beforeunload函数中发送 AJAX 请求,但这有两个问题。如果您发送异步请求,则不能保证该请求会被正确执行。如果发送同步请求,则更可靠,但浏览器将挂起,直到请求完成。如果这是一个缓慢的请求,这将给用户带来巨大的不便。

后来来了navigator.sendBeacon()通过使用该sendBeacon()方法,当用户代理有机会这样做时,将数据异步传输到Web服务器,而不会延迟卸载或影响下一次导航的性能。这解决了提交分析数据的所有问题:数据发送可靠,异步发送,不影响下一页的加载。

除非您仅针对桌面用户,sendBeacon() 否则不应与unloadbeforeunload这些用户一起使用,或者因为它们不能可靠地在移动设备上触发。相反,您可以收听该visibilitychange事件。每次您的页面可见并且用户切换选项卡、切换应用程序、进入主屏幕、接听电话、导航离开页面、关闭选项卡、刷新等时,都会触发此事件。

下面是它的用法示例:

document.addEventListener('visibilitychange', function() {
    if (document.visibilityState == 'hidden') { 
        navigator.sendBeacon("/log.php", analyticsData);
    }
});

当用户返回页面时,document.visibilityState将变为'visible',因此您也可以处理该事件。

sendBeacon()支持在:

  • 边缘 14
  • 火狐 31
  • 铬 39
  • Safari 11.1
  • 歌剧26
  • iOS Safari 11.4

目前不支持:

  • IE浏览器
  • 歌剧迷你

这是sendBeacon() 的 polyfill,以防您需要添加对不受支持的浏览器的支持。如果该方法在浏览器中不可用,它将改为发送同步 AJAX 请求。

更新:

值得一提的是,sendBeacon()它只发送POST请求。如果您需要使用任何其他方法发送请求,另一种方法是使用fetch API并将keepalive标志设置为true,这会使其行为与 相同sendBeacon()浏览器对 fetch API 的支持大致相同。

fetch(url, {
   method: ..., 
   body: ...,            
   headers: ...,       
   credentials: 'include',
   mode: 'no-cors',
   keepalive: true,
})
@cYrus,很好的收获。在发布我的答案时,MDN建议使用 unload,但他们已经改变了立场。我已经相应地更新了我的答案。
2021-03-20 01:47:13
@Peter 为了完整起见,我将其包括在内,但我删除了它。
2021-03-23 01:47:13
@Mike,请不要删除您的答案。它不仅完成选定的最佳答案(应该是您的),而且还显示用于捕获窗口退出或关闭的事件
2021-03-25 01:47:13
@AshokKumar 您可以控制发送到服务器的内容。如果您想通过 GET 发送东西,没有什么可以阻止您将请求发送到诸如http://example.com/script.php?token=something&var1=val1&var2=val2将这些值放入 GET 之类的东西。
2021-04-06 01:47:13
这个问题属于“向服务器发送请求”案例的范围。这个想法是能够在每个用户打开的标签上保持标签,并在标签关闭时在后端进行清理。
2021-04-07 01:47:13

jQuery 版本:

$(window).unload(function(){
    // Do Something
});

更新:jQuery 3:

$(window).on("unload", function(e) {
    // Do Something
});

谢谢加勒特

此处的文档鼓励侦听 onbeforeunload 事件和/或在窗口上添加事件侦听器。

window.addEventListener('beforeunload', function(event) {
  //do something here
}, false);

您也可以使用函数或函数引用填充 window 的 .onunload 或 .onbeforeunload 属性。

虽然跨浏览器的行为没有标准化,但该函数可能会返回一个值,浏览器在确认是否离开页面时将显示该值。