窗口管理

浏览器之外的 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 的浏览器引擎会在窗口上下文中呈现应用内浏览器。

在桌面 PWA 上浏览超出范围的网址时,应用内浏览器会显示此界面。

应用内浏览器的一些功能包括:

  • 它们会显示在内容上方。
  • 它们具有静态地址栏,可显示当前来源、窗口的标题和菜单。它们通常以清单的 theme_color 为主题。
  • 在上下文菜单中,您可以在浏览器中打开相应网址。
  • 用户可以关闭浏览器或返回。

当应用内浏览器显示在屏幕上时,PWA 会在后台等待,就像被另一个窗口遮挡一样。

在 iPhone 上浏览独立式 PWA 中超出范围的网址时,应用内置浏览器会显示此界面。
在 Android 上,当在独立式 PWA 中浏览超出范围的网址时,应用内置浏览器会显示此界面。

授权流程

许多 Web 身份验证和授权流程都需要将用户重定向到其他来源的其他网址,以获取返回到 PWA 来源的令牌,例如使用 OAuth 2.0

在这些情况下,应用内浏览器会遵循以下流程:

  1. 用户打开您的 PWA 并点击登录。
  2. 您的 PWA 会将用户重定向到 PWA 范围之外的网址,以便渲染引擎在您的 PWA 内打开应用内浏览器。
  3. 用户可以随时取消应用内浏览器并返回到您的 PWA。
  4. 用户登录应用内浏览器。身份验证服务器会将用户重定向到您的 PWA 来源,并将令牌作为实参发送。
  5. 当应用内浏览器检测到属于 PWA 范围的网址时,会自行关闭。
  6. 引擎会将主 PWA 窗口导航重定向到身份验证服务器在应用内浏览器中访问的网址。
  7. 您的 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"); } 

在桌面操作系统上打开了多个窗口的同一已安装 PWA。

当您在 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 设置为 automanual,在编辑宿主元素上设置虚拟键盘政策。通过政策,您可以决定是否要让浏览器自动处理虚拟键盘 (auto),还是让脚本处理虚拟键盘 (manual)。
  • 使用 CSS 环境变量获取有关虚拟键盘外观的信息,例如 keyboard-inset-heightkeyboard-inset-top

如需详细了解此 API,请参阅利用 VirtualKeyboard API 实现完全控制