javascript 无法使多屏幕窗口放置工作

x6yk4ghg  于 2023-05-21  发布在  Java
关注(0)|答案(2)|浏览(266)

我创建了一个非常简单的网站,在我的第二个屏幕上创建一个弹出窗口。
多屏幕窗口放置API承诺做到这一点,但我不能使它工作。
我得到了关于两个屏幕的所有信息,但不能在正确的显示器上打开弹出窗口。
有谁知道吗?是因为“窗口放置”许可还是什么?
以下是我制作的简单网站:

<!DOCTYPE html>
<html>

<title>Window Placement</title>

<head>
  <script type="text/javascript">
    let url = "file:///C:/Users/path/to/file.html";
    let x = "1000";
    let y = "250";
    let width = "250";
    let height = "250";
    let popup;

    async function screenDetails() {
      if (window.screen.isExtended) {
        console.log("Multiple screens detected");

        try {
          const screens = await window.getScreenDetails();

          let primary;
          let second;

          for (let element of screens.screens) {
            if (element.isPrimary) {
              primary = element;
            } else {
              second = element;
            }
          }

          let features = "left=" + x + ",top=" + y +
            ",width=" + width + ",height=" + height;

          popup = window.open(url, 'Popup', features);
        } catch (err) {
          console.error(err);
        }

      } else {
        console.log("Single screen detected");
      }
    }
  </script>
</head>

<body>
  <button type="button" onclick="open()">Open</button>
</body>

</html>
wn9m85ua

wn9m85ua1#

所以,我让它工作了,尽管不是在我提供代码的Stack Snippet环境中。
它确实与权限有关;你必须请求许可才能得到屏幕细节。在下面的代码中,我创建了一个新函数,它将查询执行此操作,下面代码中的getPermissionAndScreenDetails。它验证API是否可用,权限是否存在且未被拒绝(出于安全原因,在堆栈代码段中会自动“拒绝”)。然后,它返回调用window.getScreenDetails()的结果,因为如果state设置为“prompt”,则需要获得权限。
我修改了你的函数以使用该函数的返回值。
我还添加了一些代码,将在它找到的第一个辅助屏幕中间打开弹出窗口。

let url = "about:blank";
let x = "1000";
let y = "250";
let width = "250";
let height = "250";
let popup;

async function getPermissionAndScreenDetails() {
  if ('getScreenDetails' in window) {
    let granted = false;
    try {
      const permission = await navigator.permissions.query({
        name: 'window-placement'
      });
      console.log(permission, permission.state);
      if (permission.state !== 'denied') {
        return window.getScreenDetails();
      } else {
        return null;
      }
    } catch {
      // Nothing.
      return null;
    }
  } else {
    return null;
  }
}

async function screenDetails() {
  const screens = await getPermissionAndScreenDetails();
  if (screens != null && window.screen.isExtended) {
    console.log("Multiple screens detected");

    try {
      console.log(screens);
      let primary;
      let secondaries = [];

      for (let element of screens.screens) {
        if (element.isPrimary) {
          primary = element;
        } else {
          secondaries.push(element);
        }
      }
      console.log('primary: ', primary);
      console.log('secondaries: ', secondaries);

      // find secondary screen we can place the popup on
      const secondary = secondaries[0];
      x = secondary.left + (secondary.availWidth / 2) - (width / 2);
      y = secondary.top + (secondary.availHeight / 2) - (height / 2);

      let features = "left=" + (second.left + 1000) + ",top=" + (second.top + 400) +
        ",width=" + width + ",height=" + height;

      popup = window.open(url, 'Popup', features);
    } catch (err) {
      console.error(err);
    }

  } else {
    console.log("Single screen detected (or permission not granted)");
  }
}

document.getElementById("open").addEventListener('click', screenDetails);
<button type="button" id="open">Open</button>
vecaoik1

vecaoik12#

首先,onclick="open()"应该是onclick="screenDetails()"。接下来,硬编码的xy值应该使用availLeftavailTop等。window.open坐标的预期屏幕。而且,开启器可以在装置的辅助屏幕上;要在任何其他屏幕上打开一个窗口,您可以找到一个不是currentScreenscreens条目,就像我下面的片段一样。
除了权限,iframes还需要“窗口管理”权限策略,这就是为什么Stack Overflow的“运行代码段”在这里不起作用。
请参见https://michaelwasserman.github.io/window-placement-demo/上的API示例代码
此代码段在任何其他屏幕上打开一个窗口;测试https://husky-imaginary-sale.glitch.me/

<button id="popup">Open popup on another screen</button>
<div id="logger"></div>

<script>
function log(text) {
  console.log(text);
  logger.innerText += text + '\n';
}

popup.addEventListener('click', async () => {
  try {
    window.screenDetails = await window.getScreenDetails();
  } catch {}
  if (!window.screenDetails) {
    log('API not supported or permission denied, skipping popup');
    return;
  }
  if (!window.screenDetails.screens.length > 1) {
    log('Single screen detected, skipping popup');
    return;
  }
  const other = window.screenDetails.screens.find(s=>s!=window.screenDetails.currentScreen);
  const width = 300;
  const height = 300;
  const left = other.availLeft + (other.availWidth / 2) - (width / 2);
  const top = other.availTop + (other.availHeight / 2) - (height / 2);
  const features = `left=${left},top=${top},width=${width},height=${height}`;
  log(`Opening popup with features: '${features}'`);
  window.open('about:blank', 'Popup', features);
});
</script>

相关问题