浏览器外部的 PWA 管理其自身的窗口。了解用于在操作系统中管理窗口的 API 和功能。
在由您的 PWA 管理的自有窗口中运行,具有该操作系统中任何窗口的所有优势和责任,例如
- 在多窗口操作系统(如 Windows 或 ChromeOS)中移动和调整窗口大小的能力。
- 与其他应用窗口共享屏幕,例如 iPadOS 分屏模式或 Android 分屏模式。
- 出现在桌面上的 Dock、任务栏和 Alt+Tab 菜单中,以及移动设备上的多任务窗口列表中。
- 随时最小化、跨屏幕和桌面移动窗口以及关闭窗口的能力。
移动和调整窗口大小
在桌面操作系统上,您的 PWA 窗口可以是任意大小,并且可以放置在屏幕上的任何位置。默认情况下,当用户在安装后首次打开 PWA 时,PWA 会获得当前屏幕百分比的默认窗口大小,最大分辨率为 1920x1080,位于屏幕的左上角。
用户可以移动和调整窗口大小,浏览器会记住上次的偏好设置。下次用户打开应用时,窗口将保留上次使用时的大小和位置。
无法在清单中定义 PWA 的首选大小和位置。您只能使用 JavaScript API 重新定位和调整窗口大小。您可以使用 moveTo(x, y)
和 resizeTo(x, y)
函数,通过代码移动和调整您自己的 PWA 窗口,这些函数都属于 window
对象。
例如,您可以在 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 的菜单中,用户可以选择文件,然后选择新建窗口。您可以通过 PWA 代码使用 open()
函数打开新窗口。
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)可以将各种编辑工具放置在精确定位的窗口中。
- 虚拟交易平台可以在多个窗口中显示市场趋势,任何窗口都可以在全屏模式下查看。
- 幻灯片应用可以在内部主屏幕上显示演讲者备注,并在外部投影仪上显示演示文稿。
窗口管理 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
事件。
屏幕唤醒锁定
想象一下。您在厨房里用平板电脑查看食谱。您刚刚完成食材的准备工作。您的双手很脏,您转过身回到您的设备以阅读下一步。糟糕!屏幕变黑了!屏幕唤醒锁定 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
事件了解键盘何时出现和消失。 - 通过将
contenteditable
设置为auto
或manual
,以及使用virtualkeyboardpolicy
HTML 属性,在编辑宿主元素上设置虚拟键盘策略。策略允许您决定是否希望虚拟键盘由浏览器自动处理 (auto
) 或由您的脚本处理 (manual
)。 - 使用 CSS 环境变量获取有关虚拟键盘外观的信息,例如
keyboard-inset-height
和keyboard-inset-top
。
在 使用 VirtualKeyboard API 进行完全控制中阅读有关此 API 的更多信息。