安装提示 UX:何时、如何展示安装按钮
发布于
一句话: 捕获 beforeinstallprompt,等待有意义的用户信号,再从点击处理器中调用
prompt()——首次加载时就弹出冷启动安装弹窗几乎必然被关掉,并且会浪费你唯一的机会。
核心事件生命周期
Section titled “核心事件生命周期”let deferredPrompt = null;
// 1. 保存事件;抑制 mini-infobar。window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; showInstallAffordance(); // 展示你自己的按钮或横幅});
// 2. 仅在用户手势中触发。installButton.addEventListener('click', async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; deferredPrompt = null; // 事件只能使用一次 hideInstallAffordance(); if (outcome === 'accepted') recordInstall();});
// 3. 安装完成后清理。window.addEventListener('appinstalled', () => { deferredPrompt = null; hideInstallAffordance();});关键规则:
e.preventDefault()是阻止 mini-infobar 的唯一方式。prompt()必须在用户激活上下文(点击、触摸)中调用。在手势外调用会被静默忽略。- 已保存的事件是一次性的:一旦
userChoice解析,同一事件对象无法再次调用prompt()。 解析后清除引用;如需再次提示,重新监听事件。
Android(Chrome / Chromium)
Section titled “Android(Chrome / Chromium)”beforeinstallprompt 在浏览器的参与度启发式规则满足后触发。
Chrome 也可能在视口底部显示 mini-infobar——preventDefault() 可阻止它。
自定义页内提示让你可以选择合适的时机。用户接受后,Chrome 安装 WebAPK(而非快捷方式)
并触发 appinstalled。
iOS / Safari
Section titled “iOS / Safari”beforeinstallprompt 不会在 Safari(iOS 或 macOS)上触发。不存在编程式安装 API。
唯一的安装路径是:用户点击分享图标 → “添加到主屏幕”。你的 UX 职责是引导用户
(用指向分享图标的箭头或自定义横幅),而非自行触发对话框。
通过 window.navigator.standalone === true 检测应用是否已安装,
以避免向已安装用户显示提示。
桌面端(Chrome / Edge)
Section titled “桌面端(Chrome / Edge)”beforeinstallprompt 在 Windows、macOS、Linux 和 ChromeOS 上的 Chrome 和 Edge
中触发。安装体验打开一个对话框窗口而非底部弹出表单。地址栏中有一个小型安装图标作为
mini-infobar 的等效物。自定义 prompt() 调用可替代默认流程。安装完成后触发 appinstalled。
Firefox
Section titled “Firefox”Android 版 Firefox 支持安装(Firefox 128+),但不触发 beforeinstallprompt。
不存在 JavaScript 安装 API;用户从浏览器菜单发起安装。桌面版 Firefox 不支持 PWA 安装。
何时展示安装 UI
Section titled “何时展示安装 UI”| 信号 | 推荐操作 |
|---|---|
beforeinstallprompt 已触发 |
显示低调的安装入口(按钮或横幅)——不要用阻断式弹窗 |
| 首次页面加载,无参与行为 | 暂不操作;冷启动提示的接受率极低 |
| 用户完成关键任务(结账、读完文章、保存表单) | 此时突出显示安装按钮 |
| 用户一周内多次打开应用 | 内联标题芯片或持久底部栏 |
已安装(display-mode: standalone) |
隐藏所有安装 UI |
| iOS / Safari | 在 2–3 次访问后显示“点击分享 → 添加到主屏幕”提示 |
应避免的 UX 反模式
Section titled “应避免的 UX 反模式”- 首次加载时的阻断式弹窗。 Chrome 自身的研究表明,冷启动提示几乎总是被关掉。
- 被拒后立即再次提示。 多次拒绝后浏览器可能停止触发
beforeinstallprompt; 把每次提示机会视若珍贵。 - 把提示藏在隐秘的导航里。 让安装入口可见但不突兀。
- 遗漏 iOS 用户。
beforeinstallprompt不存在并不意味着 iOS 用户无法安装; 只是需要换一种方式引导他们。
检测已安装状态
Section titled “检测已安装状态”const isStandalone = window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true; // 仅限 Safari iOS
if (isStandalone) hideInstallAffordance();beforeinstallprompt 的浏览器支持情况各异,请查看 /compatibility/
获取最新数据。
实践检查清单
Section titled “实践检查清单”- 用
preventDefault()捕获beforeinstallprompt并存储。 - 仅在事件触发后才显示安装按钮。
- 在点击处理器内调用
prompt(),不在加载时调用。 -
userChoice解析后清除延迟事件引用。 - 监听
appinstalled以隐藏安装 UI 并记录转化。 - 独立模式检测可阻止向已安装用户显示 UI。
- 提供 iOS 回退说明(分享 → 添加到主屏幕)。