为什么会出现这个情况?
浏览器为了防止一些站点出现恶意弹窗的问题,增加了这个拦截机制。
打开window.open
的两种情况:
- 人为触发事件:如
click
事件,浏览器认为是人为触发的事件能够直接打开(不拦截) - js自动触发事件:如
异步触发
setTimeout
等,会被拦截,但是仔细分析还有如下两种情况:-
小于5s内触发:不拦截(实际上在Windows版Edge v131.0.2903.99上测试,chrome未测试
小于4990毫秒不拦截,大于等于4990毫秒拦截,实际情况请自行测试
) -
大于等于5s触发:拦截
// 拦截 setTimeout(()=>{window.open('http://baidu.com') },5000)// 不拦截 setTimeout(()=>{window.open('http://baidu.com') },3000)
-
如何解决?
正常
人为操作事件下正常打开即可
异步
打开的情况使用以下方法解决:
- 提前创建window.open窗口
const newWindow = window.open(`${env.routerPath}loading?tip=数据正在准备中,请稍后...`)
if (!newWindow) {return alert("浏览器被禁止弹出新窗口,请允许弹出窗口")
}
Q:有朋友要问了,为什么打开一个路由为
loading
的页面?
A:如果你的异步操作等待时间比较长,打开一个空页面比较单调枯燥,用户也会疑惑是不是系统有问题,所以这里建议你创建一个loading等待的页面,给用户一个友好展示,示例如下:
此页面不需要写任何逻辑,仅展示loading状态即可,因为后面第2步
会修改页面地址
- 在异步处理完成的地方写如下代码:
const url = `${env.publicPath}page1` // 异步目标跳转页面/page1
newWindow.location.href = url // 修改目标窗口的地址
newWindow.focus(); // 浏览器标签页聚焦到新窗口上