我有一个库,它提供了打开弹出选项卡的方法(它们通过 window.postMessage api 与我的应用程序交互)。
在第一种情况下,我有立即触发登录服务的登录按钮:
loginButton.addEventListener(() => {
myService.openLogin(); // everything works perfectly fine, new tab is opened
})
在第二种情况下,我有一个付款按钮,它代表在进行一些检查后打开付款窗口
paymentButton.addEventListener(() => {
dispatch({type: "todo"})
})
const myReducer = ... = {
onTodo() {
//perform a lot of checks
myService.openPayment();
}
}
我上面描述的是简而言之,实际上需要很多函数和代码,但最终调用的是服务方法。点击到
openPayment()
触发之间的时间约为300ms。
我听说有某种“点击上下文”与第二种情况不同,因此 Firefox 认为我的服务是垃圾邮件并阻止它。
不幸的是我无法重现它,只是希望有人遇到过这样的问题
以下设置允许您进行实验:
function move(from, to, via, n) {
if (n > 1)
move(from, via, to, n - 1);
to.unshift(from.shift());
if (n > 1)
move(via, to, from, n - 1);
}
function delay(n) {
var a = [];
for (var i = 0; i < n; i++) a.push(i);
var b = [];
var c = [];
move(a, b, c, a.length);
window.open("about:blank");
}
Number N: <input id="seconds" type="number" value="1" />
<button onclick="setTimeout(() => window.open('about:blank'), 1000 * seconds.value)">Timeout N seconds</button>
<button onclick="fetch('http://httpbin.org/delay/' + seconds.value).then(() => window.open('about:blank'))">Request N
seconds</button>
<button onclick="delay(Number(seconds.value))">Tower of Hanoi N levels</button>
(您无法运行嵌入的此代码片段,因为其沙盒环境无法完全打开弹出窗口。)
Google Chrome 会阻止用户活动后至少 5 秒发生的弹出窗口,无论延迟是否来自
setTimeout
、HTTP 请求,甚至是像 28 个级别的 HanoiTower 这样的同步活动(在我的计算机上,您的时间可能会有所不同)。
根据您的观察,其他浏览器可能会以不同的方式处理此类延迟。