从 PWA 触发安装
警告:此处描述的技术依赖于 beforeinstallprompt 事件,该事件不是标准事件,目前仅在基于 Chromium 的浏览器中实现。
默认情况下,如果用户访问您的网站,并且浏览器确定该网站 可以作为 PWA 安装,那么浏览器将显示一些内置 UI — 例如,URL 栏中的图标 — 来安装该网站。如果用户单击该图标,则浏览器会显示一个安装提示,其中至少包含应用的 名称 和 图标。如果用户同意安装该应用,则会进行安装。
但是,您可以实现自己的应用内 UI 来询问用户是否要安装该应用,这将触发安装提示。这样做的优点是:
- 您可以提供有关应用的更多上下文信息,向用户解释他们为什么可能想要将其安装为 PWA。
- 应用内安装 UI 可能比浏览器默认 UI 更容易被用户发现和理解。
添加应用内安装 UI
首先,在应用中添加一些 UI,表明用户可以安装它。例如:
<button id="install" hidden>Install</button>
我们设置了按钮的 hidden 属性,因为如果用户使用无法安装该应用的浏览器访问应用,我们不希望显示安装 UI。接下来,我们将看到如何仅在支持本地安装 PWA 的浏览器中显示按钮。
监听 beforeinstallprompt
一旦浏览器确定它可以安装该应用,它就会在全局 Window 范围中触发 beforeinstallprompt 事件。
在我们的主应用代码中,我们将监听此事件:
// main.js
let installPrompt = null;
const installButton = document.querySelector("#install");
window.addEventListener("beforeinstallprompt", (event) => {
event.preventDefault();
installPrompt = event;
installButton.removeAttribute("hidden");
});
这里的事件处理程序执行三项操作:
- 在事件上调用
preventDefault()。这可以阻止浏览器显示自己的安装 UI。 - 获取传递到处理程序的事件对象的引用。这是一个
BeforeInstallPromptEvent实例,它将使我们能够提示用户安装应用。 - 通过删除按钮上的
hidden属性来显示我们的应用内安装 UI。
请注意,当以下情况发生时,事件不会触发:
- PWA 已安装。
- 应用不符合 PWA 安装标准。
- 当前设备不支持安装 PWA(例如,由于缺少权限)。
触发安装提示
接下来,我们需要为我们的应用内安装按钮添加一个点击事件处理程序:
// main.js
installButton.addEventListener("click", async () => {
if (!installPrompt) {
return;
}
const result = await installPrompt.prompt();
console.log(`Install prompt was: ${result.outcome}`);
disableInAppInstallPrompt();
});
function disableInAppInstallPrompt() {
installPrompt = null;
installButton.setAttribute("hidden", "");
}
installPrompt 变量是在我们的 beforeinstallprompt 事件处理程序中与 BeforeInstallPromptEvent 对象一起初始化的。如果 installPrompt 由于任何原因未初始化,我们则不做任何操作。
否则,我们调用其 prompt() 方法。这将显示安装提示,并返回一个 Promise,该 Promise 会解析为一个对象,指示应用是否已安装。特别是,如果用户选择安装该应用,其 outcome 属性为 "accepted";如果他们关闭了提示,则为 "dismissed"。
无论哪种情况,我们都必须在调用 prompt() 后重置我们的状态,因为我们只能为每个 BeforeInstallPromptEvent 实例调用一次。因此,我们重置 installPrompt 变量并再次隐藏安装按钮。
响应应用安装
根据浏览器和平台的不同,浏览器可能仍会提供自己的 UI 来安装应用。这意味着应用仍可能在不经过我们的应用内安装 UI 的情况下进行安装。如果发生这种情况,我们希望禁用应用内安装 UI,否则将在已安装的应用中显示它。
为此,我们可以监听 appinstalled 事件,该事件在应用安装后会在全局 Window 范围内触发。
// main.js
window.addEventListener("appinstalled", () => {
disableInAppInstallPrompt();
});
function disableInAppInstallPrompt() {
installPrompt = null;
installButton.setAttribute("hidden", "");
}
响应已安装的平台特定应用
如果您有平台的特定版本应用以及 Web 应用,并且您想根据平台特定应用是否已安装来个性化 Web 应用体验。如果用户已安装平台特定应用,您可能不想邀请他们安装 PWA,并且/或者您可能希望他们前往平台特定应用查看内容。
这可以通过 Navigator.getInstalledRelatedApps() 方法来处理,该方法允许您检测已安装的相关平台特定应用(或 PWA)并做出相应响应。
例如
const relatedApps = await navigator.getInstalledRelatedApps();
// Search for a specific installed platform-specific app
const psApp = relatedApps.find((app) => app.id === "com.example.myapp");
if (psApp) {
// Update UI as appropriate
}
此方法还可以与 beforeinstallprompt 结合使用,以根据平台特定应用的可用性来抑制浏览器的安装 UI。
window.addEventListener("beforeinstallprompt", async (event) => {
const relatedApps = await navigator.getInstalledRelatedApps();
// Search for a specific installed platform-specific app
const psApp = relatedApps.find((app) => app.id === "com.example.myapp");
if (psApp) {
event.preventDefault();
// Update UI as appropriate
}
});
另见
- 使 PWA 可安装
beforeinstallprompt事件- 如何在 web.dev 上提供您自己的应用内安装体验 (2021)
- 在 web.dev 上的安装提示 (2022)