安装提示:beforeinstallprompt 与自定义安装
一句话: Chromium 系浏览器在 PWA 满足可安装性条件时触发 beforeinstallprompt;
你用 preventDefault() 抑制 mini-infobar、暂存该事件,随后在用户手势中调用
prompt() 弹出安装对话框。Safari 不触发此事件——iOS 用户通过手动“添加到主屏幕”安装。
事件流程如何工作
Section titled “事件流程如何工作”beforeinstallprompt触发 于页面变为可安装时。调用preventDefault()阻止浏览器默认的 mini-infobar,然后保存事件引用。- 由手势触发。 浏览器只在用户激活上下文(点击/触摸处理器)中允许
prompt()。 在页面加载时调用会被忽略。 - 读取结果。
await deferredPrompt.userChoice解析为{ outcome: 'accepted' | 'dismissed' }。保存的事件只能使用一次。 appinstalled触发 于安装成功后(无论来自你的提示还是浏览器自带 UI)。 用它来隐藏安装按钮并记录转化。
let deferredPrompt = null;
window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; installButton.hidden = false;});
installButton.addEventListener('click', async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; deferredPrompt = null; installButton.hidden = true;});
window.addEventListener('appinstalled', () => { installButton.hidden = true;});可安装性条件
Section titled “可安装性条件”要让 beforeinstallprompt 触发,页面必须通过 HTTPS 提供服务(localhost 除外),
并链接一个 Web 应用清单,其中至少声明 name(或 short_name)、start_url、
一个非 browser 的 display 值,以及图标(含 192px 与 512px 的 PNG)。多数
Chromium 浏览器还要求注册 Service Worker(推荐带 fetch 处理器,尽管纯离线行为
已不再处处强制)。缺少任一项都不会触发事件。
浏览器与生态支持
Section titled “浏览器与生态支持”| Browser / Platform | Support | Since | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Android) | ✅ yes | 68 | high | ref | — |
| Chrome (Desktop) | ✅ yes | 73 | high | ref | — |
| Edge (Desktop) | ✅ yes | 79 | high | ref | — |
| Safari (iOS) | ❌ no | — | high | ref | No beforeinstallprompt; install is manual via the Share sheet → Add to Home Screen. |
| Safari (macOS) | ❌ no | — | high | ref | Install is via the File → Add to Dock menu, not the web event. |
| Firefox (Desktop) | ❌ no | — | high | ref | No manifest-based desktop install path. |
| Samsung Internet | ✅ yes | 9.0 | medium | ref | — |
iOS 与 Safari 有何不同
Section titled “iOS 与 Safari 有何不同”- 无
beforeinstallprompt。 Safari(iOS 与 macOS)从不触发该事件,也不暴露 任何编程式安装 API,因此页面内自定义按钮无法触发安装。 - 手动添加到主屏幕。 iOS 用户点击“分享”,再点“添加到主屏幕”。你只能用说明 和指向分享图标的视觉提示来引导他们。
- 检测独立模式:用
navigator.standalone(iOS)或window.matchMedia('(display-mode: standalone)')来避免向已安装用户重复提示。
何时呈现自定义安装按钮
Section titled “何时呈现自定义安装按钮”| 情形 | 建议行为 | 理由 |
|---|---|---|
beforeinstallprompt 已触发并保存 |
显示克制的安装入口,而非阻断式模态 | 浏览器已确认可安装;尊重用户流程 |
| 用户刚进入、尚无任何互动 | 等待——不要在首屏就提示 | 冷提示易被关闭,并可能浪费你唯一的机会 |
| 用户完成了有意义的操作 | 此时呈现安装按钮 | 意图强烈;转化率高得多 |
| 已安装(独立模式) | 隐藏所有安装 UI | 向已安装应用提示只是令人困惑的噪音 |
| iOS / Safari | 显示手动“添加到主屏幕”说明 | 不存在编程式提示;改为指引 |
- 核实 HTTPS、已链接的清单、192px + 512px 图标,以及已注册的 Service Worker。
- 在
beforeinstallprompt中调用e.preventDefault()并暂存事件。 - 只在点击/触摸处理器内(用户手势)调用
prompt()。 - 将延迟事件视为一次性;在
userChoice解析后清除它。 - 监听
appinstalled以隐藏按钮并记录转化。 - 检测独立模式,对已安装用户抑制安装 UI。
- 为 iOS/Safari 提供回退方案,附明确的“添加到主屏幕”指引。