window.open('', '测试');打开一个新的“about:blank”窗口,而不是聚焦现有的“test”窗口

问题描述 投票:0回答:1

我有一个可以打开多个外部弹出窗口的网络应用程序,例如:

window.open('https://stackoverflow.com/', 'stackoverflow')

最终用户可以打开我的应用程序的多个窗口,但我希望目标只存在一个窗口。我采用的解决方案是

BroadcastChannel
,用于在我的应用程序实例之间共享信息(如果目标窗口已打开)。

broadcastChannel.postMessage({ type: 'open', value: 'stackoverflow'});
window.open('https://stackoverflow.com/', 'stackoverflow');

所有应用程序实例都会侦听消息并收集打开的目标窗口

 const openWindowsTarget = [];
 broadcastChannel.onmessage = (event) => {
    if( event.data.type === 'open' ){
        openWindowsTarget.push(event.data.value);
    }
 }

这样,如果在某处打开目标窗口,则该窗口将在没有 url 的情况下打开,仅带有目标

 if (openWindowsTarget.includes('stackoverflow') ) {
    window.open('', 'stackoverflow');
 } 

这样窗口只是聚焦,无需重新加载。

此行为在过去有效,但在当今,效果是打开一个新的“about:blank”窗口。可能是浏览器端发生了一些变化。

我正在寻找解决方案来修复!

为了测试/帮助将此代码段保存到 html 文件(example.html)中,打开两个单独的窗口并单击按钮

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <button onclick="openWindow('https://stackoverflow.com/', 'stackoverflow')">
      Open stackoverflow
    </button>
    <script>
      const broadcastChannel = new BroadcastChannel('WindowService');
      const openWindowsTarget = [];

      broadcastChannel.onmessage = (event) => {
        if (event.data.type === 'open') {
          openWindowsTarget.push(event.data.value);
          console.log({openWindowsTarget})
        }
      };

      function openWindow(url, target) {
        if (openWindowsTarget.includes(target)) {
          window.open('', target);
        } else {
          broadcastChannel.postMessage({ type: 'open', value: target });
          openWindowsTarget.push(target);
          window.open(url, target);
        }
      }
    </script>
  </body>
</html>

我也尝试过改变方法并发送广播消息以将窗口聚焦,但是

focus()
没有效果,如果窗口最小化,它仍然最小化

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <button onclick="openWindow('https://stackoverflow.com/', 'stackoverflow')">
      Open stackoverflow
    </button>
    <script>
      const broadcastChannel = new BroadcastChannel('WindowService');
      const openWindowsTarget = [];
      const localWindows = {};

      broadcastChannel.onmessage = (event) => {
        if (event.data.type === 'open') {
          openWindowsTarget.push(event.data.value);
          console.log({openWindowsTarget})
        }
        if (event.data.type === 'focus') {
            if( localWindows[event.data.value] ){
                localWindows[event.data.value].focus();
            }
        }
      };

      function openWindow(url, target) {
        if (openWindowsTarget.includes(target)) {
          broadcastChannel.postMessage({ type: 'focus', value: target });
        } else {
          broadcastChannel.postMessage({ type: 'open', value: target });
          openWindowsTarget.push(target);
          localWindows[target] = window.open(url, target);
        }
      }
    </script>
  </body>
</html>

还有其他想法吗?

javascript popup broadcast-channel
1个回答
0
投票

也许检查窗口是否存在的解决方案是合适的。虽然你原来的脚本没有给我带来任何问题。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  
<script>
let windowObjectReference = null; // global variable
function openRequestedTab(url, windowName) {
  if (windowObjectReference === null || windowObjectReference.closed) {
    windowObjectReference = window.open(url, windowName);
  } else {
    windowObjectReference.focus();
  }
}
</script>

  <body>
    <button onclick="openRequestedTab('https://stackoverflow.com/', 'stackoverflow')">
      Open or create a window named `stackoverflow`
    </button> 
  </body>
  
</html>
© www.soinside.com 2019 - 2024. All rights reserved.