这篇文章发布于 2026年07月29日,星期三,11:27,归类于 JS API。 阅读 45 次, 今日 44 次 没有评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12253
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
一、如何判断是多显示器
screen.isExtended属性和window.getScreenDetails()都可以判断当前用户是否是多显示器。
代码示意:
if (screen.isExtended) {
console.log("用户拥有多显示器");
}
例如,阿拉的电脑现在就插着外接显示器,运行的结果就是 true.

我们也可以使用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都没有支持。

二、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
例如,下面截图示意的就是我当前两个显示器的基础信息显示:

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

相关源码大家可以右键页面查看,或者让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六小时特价,同样爆箱,大昂刺鲫鱼鳊鱼,好搞好搞。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12253
(本篇完)
- 关于Google圆角高光高宽自适应按钮及其拓展 (0.347)
- 我熟知的三种三栏网页宽度自适应布局方法 (0.347)
- 像素的世界及其在web开发制作中的应用 (0.347)
- 热门:响应图片(Responsive Images)技术简介 (0.347)
- ajax与HTML5 history pushState/replaceState实例 (0.248)
- mobilebone.js-mobile移动web APP单页切换骨架 (0.248)
- JS获取上一访问页面URL地址document.referrer实践 (0.248)
- 如何让MP4 video视频背景色变成透明? (0.248)
- 深入理解CSS mix-blend-mode滤色screen混合模式 (0.248)
- FDCon2019大会分享之滤镜与混合模式实录 (0.248)
- 快速了解window.name特性与作用 (RANDOM - 0.158)