在卸载事件之前有什么限制?

时间:2017-01-28 11:40:21

标签: javascript browser

beforeunload回调中有什么内容和不可以做什么?

是否可以打开XHR / fetch并将数据发送到服务器?  如果不是,是否可以只发送数据,而没有任何成功的回调阻止?

是否可以使用window.location更改页面的位置? 功能继续执行多长时间?

window.addEventListener("beforeunload", function (event) {
    // code
});

2 个答案:

答案 0 :(得分:23)

你可以把任何你想要的东西放在" beforeunload"回调,你不能保证它会执行,除非你使用同步/阻塞代码。

这是一个阻止睡眠功能,我将用于演示目的:

function sleep(delay) {
  var start = new Date().getTime();
  while (new Date().getTime() < start + delay);
}

任何同步阻塞代码都可以保证执行完成:

window.addEventListener("beforeunload", function (event) {
  console.log("Blocking for 1 second...");
  sleep(1000);
  console.log("Done!!");
});

任何异步代码(即带有回调的代码)都会在事件循环中排队,但它可能会也可能不会完成执行,具体取决于浏览器何时完成&#34;卸载&#34;动作(例如关闭窗口,刷新页面。)这里的时间真的取决于您的计算机的性能。例如,在我的计算机上,由于我的浏览器没有时间刷新/关闭页面,因此仍然会执行10ms的超时日志语句。

window.addEventListener("beforeunload", function (event) {
  setTimeout(() => {
    console.log("Timeout finished!"); // Odds are this will finish
  }, 10);
  console.log("Done!!");
});

但是,永远不会执行100ms的超时:

window.addEventListener("beforeunload", function (event) {
  setTimeout(() => {
    console.log("Timeout finished!");
  }, 100);
  console.log("Done!!");
});

保证函数运行完成的唯一方法是确保您编写阻止事件循环的同步代码,如第一个示例所示。

答案 1 :(得分:0)

要在第一个答案的评论中帮助某些人,请查看此功能以在卸载事件期间发出XHR请求:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon