Screen.isExtended、getScreenDetails与多显示器开发

这篇文章发布于 2026年07月29日,星期三,11:27,归类于 JS API。 阅读 77 次, 今日 76 次 没有评论

 

一、如何判断是多显示器

screen.isExtended属性和window.getScreenDetails()都可以判断当前用户是否是多显示器。

代码示意:

if (screen.isExtended) {
    console.log("用户拥有多显示器");
}

例如,阿拉的电脑现在就插着外接显示器,运行的结果就是 true.

screen.isExtended运行结果

我们也可以使用window.getScreenDetails()判断用户是否拥有多个显示器。

代码示意:

async function checkMultipleScreens() {
  if ("getScreenDetails" in window) {
    try {
      // 注意:必须在用户交互(如点击事件)中触发,否则会抛出异常
      const screenDetails = await window.getScreenDetails();
      
      // 3. 通过 screens 数组长度精准判断
      const isMultiMonitor = screenDetails.screens.length > 1;
      console.log(`屏幕总数: ${screenDetails.screens.length}`);
      
      return isMultiMonitor;
    } catch (err) {
      console.error("用户拒绝授权或调用失败", err);
      return false;
    }
  } else {
    console.log("当前浏览器不支持 getScreenDetails");
    return false;
  }
}

getScreenDetails()方法返回的是个Promise,第一次执行的时候,浏览器会出现权限申请提示,如下截图所示:

管理显示器提示

如果用户点击“屏蔽”,则会返回NotAllowedError错误:

Uncaught (in promise) NotAllowedError: Permission denied.

此时,我们可以点击地址栏前面的小图标,将权限开启,如下截图所示:

开启窗口管理权限

可见,如果只是单纯判断显示器是否包含多个,一定是使用screen.isExtended属性,只有需要精确知道显示器个数的时候,才需要考虑getScreenDetails()方法。

这两个特性的兼容性都是一样的,都是Chrome 100支持的,目前Firefox和Safari都没有支持。

窗口管理API的兼容性

二、Management API与窗口开发

下面讲下如何更加智能地控制新窗口打开这一交互。

之前我们都是使用window.open()来打开新窗口、调整现有窗口的大小以及关闭现有窗口等。

例如,要在屏幕的左上方50px处打开一个800×600的窗口:

const myWindow = window.open(
  "https://www.zhangxinxu.com/",
  "myWindow",
  "left=50,top=50,width=800,height=600",
);

然而,上述功能存在局限性。

window.screen只能返回主屏幕的数据,而不包括设备可用的辅助显示器。

如果我们想要要将窗口移动到辅助显示器,虽然可以使用window.moveTo()方法,但你具体的坐标需要通过猜测才能得到,这显然不太靠谱。

window.getScreenDetails()方法可以返回所有屏幕的具体信息,此时,我们就可以精准控制新窗口的尺寸和位置。

我们来看几个案例。

1. 指定在第一屏第二屏显示

您可以狠狠地点击这里:Window Management API 多屏显示演示

如果你有多个显示屏,那么点击下图所示的按钮:

按钮点击示意

会出现窗口管理的权限提示,这里点击运行。

然后,还会出现“请禁用弹窗拦截”的自定义提示,此时,点击地址栏右侧的图标,开启允许弹出式窗口,如下截图所示。

允许弹出式窗口

然后再次点击按钮,就会看到第一屏平铺了三个窗口,第二屏则是一个全屏窗口,截图示意如下:

多窗口打开示意

然后关闭任意窗口,其他窗口都会关闭。

相关的运行代码参考:

const screenDetails = await window.getScreenDetails();
if (screenDetails.screens.length > 1) {
  const screen1 = screenDetails.screens[0];
  const screen2 = screenDetails.screens[1];
  // 1/3窗口宽度,100%窗口高度
  const windowWidth = Math.floor(screen1.availWidth / 3);
  const windowHeight = screen1.availHeight;

  //主屏打开三个参考窗口
  openWindow(screen1.availLeft,
    screen1.availTop,
    windowWidth,
    windowHeight,
    sites[1].url);
  openWindow(screen1.availLeft + windowWidth,
    screen1.availTop,
    windowWidth,
    windowHeight,
    sites[2].url);
  openWindow(screen1.availLeft + windowWidth * 2),
    screen1.availTop,
    windowWidth,
    windowHeight,
    sites[3].url);

  // 副屏打开一个全屏窗口
  openWindow(screen2.availLeft,
    screen2.availTop,
    screen2.availWidth,
    screen2.availHeight,
    sites[0].url);
}

窗口关闭的原理示意如下:

const windowRef = window.open(
  url,
  "_blank",
  windowFeatures,
);

// 如果需要关闭
windowRef.close();

2. 屏幕信息获取、打开指定窗口,全屏处理等

您可以狠狠地点击这里:屏幕切换显示、全屏、信息获取等综合演示demo

例如,下面截图示意的就是我当前两个显示器的基础信息显示:

显示器屏幕信息示意

其他一些功能,大家可以点击演示页面对应按钮体验,这里就不赘述了。

demo页面交互按钮截图示意

相关源码大家可以右键页面查看,或者让AI帮你分析。

三、ScreenDetails属性、事件以及屏幕信息获取

getScreenDetails()方法会返回ScreenDetails对象。

ScreenDetails对象包含属性和事件各两个,如下示意。

属性

currentscreen

返回一个单独的ScreenDetailed对象,表示当前浏览器窗口所显示屏幕的详细信息。

screens

ScreenDetailed对象数组,包含所有屏幕信息(注意,镜像屏幕不在其中)。

方法

currentscreenchange

当窗口的当前屏幕以某种方式发生变化时触发,例如可用宽度或高度,或方向发生了变化。

screenschange

当屏幕与系统连接或断开时触发。

ScreenDetailed对象包含屏幕的位置尺寸等信息。

参数名称 (Property) 读写权限 (Access) 数据类型 (Type) 功能描述 (Description)

availLeft
只读 (Read only) 数字 (Number) 表示可用屏幕区域的 X 轴坐标(左侧边缘位置)。

availTop
只读 (Read only) 数字 (Number) 表示可用屏幕区域的 Y 轴坐标(顶部边缘位置)。

devicePixelRatio
只读 (Read only) 数字 (Number) 表示该屏幕的设备像素比(DPR)。

isInternal
只读 (Read only) 布尔值 (Boolean) 指示该屏幕是设备的内置(内部)显示器还是外接(外部)显示器。

isPrimary
只读 (Read only) 布值 (Boolean) 指示该屏幕是否被操作系统(OS)设置为主显示器。

label
只读 (Read only) 字符串 (String) 提供该屏幕的描述性名称标签,例如 “Built-in Retina Display”(内置视网膜显示屏)。

left
只读 (Read only) 数字 (Number) 表示整个屏幕总区域的 X 轴坐标(左侧边缘位置)。

top
只读 (Read only) 数字 (Number) 表示整个屏幕总区域的 Y 轴坐标(顶部边缘位置)。

基本上我们日常开发,就是围绕上述这些属性值进行的。

四、欧拉结语喵了个咪的

点评下吧。

本文介绍的Window Management API算是对过往新窗口打开这套实现的增强与补充。

不过由于在实操过程中,有过多的权限申请,还需要用户允许新窗口打开,对齐应用前景我不太看好。

只能用在某些特殊的交互场合。

例如,新窗口模式的支付弹框,成功后自动关闭这种。

倒是screen.isExtended这个判断屏幕数量的属性使用简单,说不定以后会经常被使用。

不过眼下受制于兼容性,暂时还看不到在生产环境实践的可能。

唉,注定又是一个冷门特性。

行了,就说这么多吧,最后秀下周末两场的渔获。

周六鱼泡钓场,168六小时,草鱼爆箱,11条草鱼还有翘嘴鳊鱼罗非。

周日阿坤钓场,99六小时特价,同样爆箱,大昂刺鲫鱼鳊鱼,好搞好搞。

渔获展示

(本篇完)

分享到:


发表评论(目前没有评论)