從 PWA 觸發安裝

警告:此處描述的技術依賴於 beforeinstallprompt 事件,該事件不是標準事件,目前僅在基於 Chromium 的瀏覽器中實現。

預設情況下,如果使用者訪問您的網站,並且瀏覽器確定該網站 可以作為 PWA 安裝,那麼瀏覽器將顯示一些內建 UI — 例如,URL 欄中的圖示 — 來安裝該網站。如果使用者單擊該圖示,則瀏覽器會顯示一個安裝提示,其中至少包含應用的 名稱圖示。如果使用者同意安裝該應用,則會進行安裝。

但是,您可以實現自己的應用內 UI 來詢問使用者是否要安裝該應用,這將觸發安裝提示。這樣做的優點是:

  • 您可以提供有關應用的更多上下文資訊,向用戶解釋他們為什麼可能想要將其安裝為 PWA。
  • 應用內安裝 UI 可能比瀏覽器預設 UI 更容易被使用者發現和理解。

新增應用內安裝 UI

首先,在應用中新增一些 UI,表明使用者可以安裝它。例如:

html
<button id="install" hidden>Install</button>

我們設定了按鈕的 hidden 屬性,因為如果使用者使用無法安裝該應用的瀏覽器訪問應用,我們不希望顯示安裝 UI。接下來,我們將看到如何僅在支援本地安裝 PWA 的瀏覽器中顯示按鈕。

監聽 beforeinstallprompt

一旦瀏覽器確定它可以安裝該應用,它就會在全域性 Window 範圍中觸發 beforeinstallprompt 事件。

在我們的主應用程式碼中,我們將監聽此事件:

js
// 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(例如,由於缺少許可權)。

觸發安裝提示

接下來,我們需要為我們的應用內安裝按鈕新增一個點選事件處理程式:

js
// 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 範圍內觸發。

js
// main.js

window.addEventListener("appinstalled", () => {
  disableInAppInstallPrompt();
});

function disableInAppInstallPrompt() {
  installPrompt = null;
  installButton.setAttribute("hidden", "");
}

響應已安裝的平臺特定應用

如果您有平臺的特定版本應用以及 Web 應用,並且您想根據平臺特定應用是否已安裝來個性化 Web 應用體驗。如果使用者已安裝平臺特定應用,您可能不想邀請他們安裝 PWA,並且/或者您可能希望他們前往平臺特定應用檢視內容。

這可以透過 Navigator.getInstalledRelatedApps() 方法來處理,該方法允許您檢測已安裝的相關平臺特定應用(或 PWA)並做出相應響應。

例如

js
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。

js
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
  }
});

另見