Open Window Async

JavaScript

一般情况下,只有当用户有操作的情况下,在一个 tick 里,JavaScript 通过 window.open 或是 <a target="_blank"> HTML 元素直接 click 打开新的窗口才能正常弹出。如果一旦涉及到异步的操作,弹框就会默认被浏览器阻止,无法正常显示。

这样设计的初衷,是为了防止前端随意弹框,影响到用户正常的体验。然而,在某些情况下,用户操作后需要经过网络请求,返回结果后才知道应该如何展示弹框。这种情况下,简单的 fetch().then(() => window.open()) 肯定是不行的。需要一些 Hack 的方案,如下。

在用户进行了操作之后,首先先打开一个新的窗口,等到异步操作返回之后,再通过 JavaScript 修改这个窗口的地址,从而达到异步打开窗口的目的。示例代码如下:

element.onclick = async () => {
  const win = window.open('');
  // 模拟异步操作
  await sleep(5000);
  win.location.href = 'actual location';
};

这样操作可能的问题及解决方法:

  1. 如果在异步的过程中本窗口被关闭了,就会留下一个空白的新窗口。因而,需要监听 beforeunload 事件,以保证必要时候可以关闭新打开的窗口;
  2. 如果异步的时间比较长,打开一个空白的窗口用户体验较差(打开后默认会获得焦点)。这种情况下,可以打开一个静态的页面,展示一个 loading 的 UI 以告诉用户当前正在进行的操作。待异步操作完成,再通过 postMessage 等方式通知窗口进行页面的跳转。