浏览器之外的 PWA 会自行管理其窗口。了解用于管理操作系统中窗口的 API 和功能。
在由 PWA 管理的自有窗口中运行,具有该操作系统中任何窗口的所有优势和责任,例如:
- 在多窗口操作系统(例如 Windows 或 ChromeOS)中移动和调整窗口大小的功能。
- 与其他应用窗口共享屏幕,如 iPadOS 分屏模式或 Android 分屏模式。
- 显示在桌面设备的 Dock、任务栏和 Alt-Tab 菜单中,以及移动设备的多任务窗口列表中。
- 能够随时最小化窗口、在屏幕和桌面之间移动窗口以及关闭窗口。
移动窗口和调整窗口大小
在桌面操作系统上,PWA 窗口可以具有任意大小,并且可以放置在屏幕上的任意位置。默认情况下,当用户在安装后首次打开 PWA 时,PWA 会获得一个默认窗口大小,该大小为当前屏幕的百分比,最大分辨率为 1920x1080,位于屏幕的左上角。
用户可以移动和调整窗口大小,浏览器会记住上次的偏好设置。用户下次打开应用时,窗口将保留上次使用时的尺寸和位置。
无法在清单中定义 PWA 的首选大小和位置。您只能使用 JavaScript API 重新定位和调整窗口大小。在代码中,您可以使用 window
对象的 moveTo(x, y)
和 resizeTo(x, y)
函数移动和调整自己的 PWA 窗口。
例如,您可以在 PWA 加载时使用以下代码调整 PWA 窗口的大小并移动该窗口:
document.addEventListener("DOMContentLoaded", event => { // we can move only if we are not in a browser's tab isBrowser = matchMedia("(display-mode: browser)").matches; if (!isBrowser) { window.moveTo(16, 16); window.resizeTo(800, 600); } });
您可以使用 window.screen
对象查询当前屏幕尺寸和位置;您可以使用 window
对象的 resize
事件检测窗口何时调整大小。没有用于捕获窗口移动的事件,因此您可以选择频繁查询位置。
您可以使用 moveBy()
和 resizeBy()
相对移动和调整窗口大小,而不是绝对移动和调整窗口大小。
浏览其他网站
如果您想将用户发送到 PWA 范围之外的外部网站,可以使用标准 <a href>
HTML 元素来实现。使用 location.href
或在兼容的平台上打开新窗口。
当您访问清单范围之外的网址时,PWA 的浏览器引擎会在窗口上下文中呈现应用内浏览器。
应用内浏览器的一些功能包括:
- 它们会显示在内容上方。
- 它们具有静态地址栏,可显示当前来源、窗口的标题和菜单。它们通常以清单的
theme_color
为主题。 - 在上下文菜单中,您可以在浏览器中打开相应网址。
- 用户可以关闭浏览器或返回。
当应用内浏览器显示在屏幕上时,PWA 会在后台等待,就像被另一个窗口遮挡一样。


授权流程
许多 Web 身份验证和授权流程都需要将用户重定向到其他来源的其他网址,以获取返回到 PWA 来源的令牌,例如使用 OAuth 2.0。
在这些情况下,应用内浏览器会遵循以下流程:
- 用户打开您的 PWA 并点击登录。
- 您的 PWA 会将用户重定向到 PWA 范围之外的网址,以便渲染引擎在您的 PWA 内打开应用内浏览器。
- 用户可以随时取消应用内浏览器并返回到您的 PWA。
- 用户登录应用内浏览器。身份验证服务器会将用户重定向到您的 PWA 来源,并将令牌作为实参发送。
- 当应用内浏览器检测到属于 PWA 范围的网址时,会自行关闭。
- 引擎会将主 PWA 窗口导航重定向到身份验证服务器在应用内浏览器中访问的网址。
- 您的 PWA 会获取令牌、存储令牌并呈现 PWA。
强制执行浏览器的导航操作
如果您想强制使用浏览器(而非应用内浏览器)打开网址,可以使用 <a href>
元素的 _blank
目标。此功能仅适用于桌面 PWA。在移动设备上,无法选择使用网址打开浏览器。
function openBrowser(url) { window.open("url", "_blank", ""); }
打开新窗口
在桌面设备上,用户可以打开同一 PWA 的多个窗口。每个窗口都具有不同的 start_url
导航,就像您打开了两个具有相同网址的浏览器标签页一样。 在 PWA 的菜单中,用户可以选择文件,然后选择新窗口。您可以使用 open()
函数从 PWA 代码中打开新窗口。
function openNewWindow() { window.open("/", "new-window", "width=600,height=600"); }
当您在 iOS 或 iPadOS 上的 PWA 窗口中调用 open()
时,它会返回 null
且不会打开窗口。在 Android 上打开新窗口会为网址创建一个新的应用内浏览器,即使该网址在 PWA 的范围内也是如此,这通常不会触发外部浏览体验。
窗口标题
<title>
元素主要用于 SEO 目的,因为浏览器标签页中的空间有限。当您从浏览器切换到 PWA 中的窗口时,整个标题栏空间都可供您使用。
您可以定义标题栏的内容:
- 静态地位于 HTML
<title>
元素中。 - 随时动态更改
document.title
字符串属性。
在桌面 PWA 上,标题至关重要,它会显示在窗口的标题栏中,有时还会显示在任务管理器或多任务选择中。如果您使用的是单页应用,则可能需要在每个路由上更新标题。
标签页模式
标签页模式是一项实验性功能,可让您的 PWA 采用基于标签页的设计,类似于 Web 浏览器。在这种情况下,用户可以在同一 PWA 中打开多个标签页,但所有标签页都绑定在同一操作系统窗口中。
如需详细了解此实验性功能,请参阅 PWA 的标签页式应用模式。
窗口控件叠加层
我们之前提到过,您可以通过定义 <title>
元素或 document.title
属性的值来更改窗口的标题。但始终是字符串值。如果我们能使用 HTML、CSS 和图片设计标题栏,会怎么样? Microsoft Edge 和 Google Chrome 中针对桌面 PWA 的实验性功能“窗口控件叠加层”或许能帮到您。
如需详细了解此功能,请参阅自定义 PWA 标题栏的窗口控件叠加层。
窗口管理
用户希望在多屏设备上充分利用所有可用空间。例如:
- Gimp 等多窗口图形编辑器可以将各种编辑工具放置在位置精确的窗口中。
- 虚拟交易平台可以在多个窗口中显示市场趋势,并且任何窗口都可以全屏模式查看。
- 幻灯片应用可以在内部主屏幕上显示演讲者备注,并在外部投影仪上显示演示文稿。
借助 Window Management API,PWA 可以做到这一点,甚至更多。
获取屏幕详细信息
窗口管理 API 新增了一个方法 window.getScreenDetails()
,该方法会返回一个对象,其中包含屏幕作为附加屏幕的不可变数组。还有一个可从 ScreenDetails.currentScreen
访问的实时对象,对应于当前的 window.screen
。
当 screens
数组发生变化时,返回的对象还会触发 screenschange
事件。(更改单个屏幕上的属性时不会发生这种情况。)当各个界面(无论是 window.screen
还是 screens
数组中的界面)的属性发生变化时,也会触发 change
事件。
// Request an object with a screen objects const screenDetails = await window.getScreenDetails(); screenDetails.screens[0].isPrimary; // e.g. true screenDetails.screens[0].isInternal; // e.g. true screenDetails.screens[0].label; // e.g. 'Samsung Electric Company 28"' // Access the live object corresponding to the current `window.screen`. // The object is updated on cross-screen window placements or device changes. screenDetails.currentScreen; screenDetails.addEventListener('screenschange', function() { // NOTE: Does not fire on changes to attributes of individual screens. const screenCount = screenDetails.screens.length; const currentScreen screenDetails.currentScreen.id; });
如果用户或操作系统将 PWA 的窗口从一个屏幕移动到另一个屏幕,屏幕详细信息对象也会触发 currentscreenchange
事件。
屏幕唤醒锁定
想象一下。您正在厨房里,按照平板电脑上的食谱做菜。您刚刚完成了食材准备工作。你弄得满手都是,于是转过身,想看看设备上显示的下一步操作。惨了!屏幕变黑了!Screen Wake Lock API 可让 PWA 防止屏幕变暗、进入休眠状态或锁定,让用户可以随时停止、开始、离开和返回,而无需担心。
// Request a screen wake lock const wakeLock = await navigator.wakeLock.request(); // Listen for wake lock release wakeLock.addEventListener('release', () => { console.log(`Screen Wake Lock released: ${wakeLock.released}`); }); // Manually release the wake lock wakeLock.release();
虚拟键盘
基于触控的设备(例如手机和平板电脑)提供虚拟屏幕键盘,以便用户在 PWA 的表单元素获得焦点时进行输入。
借助 VirtualKeyboard API,您的 PWA 可以使用 navigator.virtualKeyboard
接口在兼容的平台上更好地控制键盘。
- 使用
navigator.virtualKeyboard.show()
和navigator.virtualKeyboard.hide()
显示和隐藏虚拟键盘。 - 通过将
navigator.virtualKeyboard.overlaysContent
设置为true
,告知浏览器您要自行关闭虚拟键盘。 - 通过
geometrychange
事件了解键盘何时显示和消失。 - 通过使用
virtualkeyboardpolicy
HTML 属性将contenteditable
设置为auto
或manual
,在编辑宿主元素上设置虚拟键盘政策。通过政策,您可以决定是否要让浏览器自动处理虚拟键盘 (auto
),还是让脚本处理虚拟键盘 (manual
)。 - 使用 CSS 环境变量获取有关虚拟键盘外观的信息,例如
keyboard-inset-height
和keyboard-inset-top
。
如需详细了解此 API,请参阅利用 VirtualKeyboard API 实现完全控制。