有些浏览器会为了用户体验和安全考虑,拦截一些非用户行为触发的回调中执行的敏感操作。例如,在setTimeout函数中调用window.open,或者使用 DOM 元素的focus方法。为了解决这个问题,通常的解决方法是在用户事件回调函数中同步地调用这些方法,然后在异步回调中执行后续操作,以 window.open 为例:

someDOMElement.onclick = () => {
  const win = window.open('about:blank', '_blank');
  setTimeout(() => {
    win.location.href = "http://...."
  }, 500)
}

上述代码中, 我们在事件回调中立即调用 window.open 方法打开一个空白页面,等待异步回调触发后,再填充空白页面的链接, 这样就可以防止被浏览器拦截。

focus 获取焦点无法弹出窗口的解决方法也类似如此,但是要借助一个临时的 DOM 节点:

document.body.ontouchend = function(){
    const tmpElement = document.createElement('input');
    tmpElement.style.cssText += `
      width: 0;
      height: 0;
      margin: 0;
      padding: 0;
      border: 0;
      opacity: 0;
    `;
    document.body.appendChild(tmpElement);
    tmpElement.focus();

    asyncMethod().then(function(){
        inpuf.focus();
        tmpElement.remove();
    });
}
posted on 2023-08-07 15:04  y1j2x34  阅读(118)  评论(0)    收藏  举报