检测是否通过不相关的功能取消了beforeunload事件

时间:2019-02-18 04:14:55

标签: javascript jquery

我有一个简单的功能,可以在发出新页面请求时显示微调器叠加层。

$(window).on("beforeunload", function() {
  $('#nav-spinner').show();
});

这很好用..但是,它在复杂的WordPress网站上使用,并且其他(第三方)组件也使用此事件有时会取消导航(例如,从部分填充的导航中确认时形式)。

有什么方法可以确定另一个功能是否取消了页面卸载,因此当它们覆盖在页面上时,我可以立即删除它。

我想在取消实际导航时执行此操作-使用计时器删除叠加层会导致叠加层被过早隐藏或保留的时间比应有的长。

1 个答案:

答案 0 :(得分:1)

显示问题的测试用例

因此,以下代码显示了您当前拥有的内容。我将背景设置为红色,因为这是最少的代码。

window.addEventListener("beforeunload", function(event) {
  document.body.classList.add("red");
});

// 3rd party code that is showing the "are you sure"
window.addEventListener("beforeunload", function(event) {
  event.preventDefault();
  event.returnValue = 'I am 3rd party code';
});
.red {
  background-color: red;
}
<form>
  <button>Click Me then click "Cancel"</button>
</form>

解决问题

因此,现在我们有了错误情况的测试用例。当用户单击“取消”时,背景不应保持红色。那么我们如何检测到它呢?嗯,没有事件可以告诉您用户的行为。

因此,您唯一可以做的就是添加一个计时器,以在用户取消添加时删除添加的内容。因此,如果他们单击“取消”,计时器将运行并删除它。

但是,如果他们不取消它,我们如何将其保留在那里?我们使用卸载来杀死隐藏它的超时。因此,请删除超时,它将不会触发。

var timer
// update the page as page exits
window.addEventListener("beforeunload", function(event) {
  document.body.classList.add("red");
  // if this timer runs, it means beforeunload was cancelled 
  timer = window.setTimeout( function () {
    document.body.classList.remove("red");
  }, 50);
});
   // remove the timer when the pages finally exits so the class is not removed.
window.addEventListener("unload", function(event) {
  window.clearTimeout(timer)
})


 // 3rd party code that is showing the "are you sure"
window.addEventListener("beforeunload", function(event) {
  event.preventDefault();
  event.returnValue = 'I am 3rd party code';
});
.red {
  background-color: red;
}
<form>
  <button>Click Me then click "Cancel"</button>
</form>

您可能必须使用超时毫秒值。可以通过过渡来减少用于显示的内容的闪烁,但是希望浏览器不会终止该卸载。