从您的 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。
触发安装提示
接下来,我们需要为我们的应用内安装按钮添加一个点击处理程序
// 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
,该提示将解析为一个对象,指示应用是否已安装。特别是,其 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
}
});