4. 实现添加到主屏幕

任务说明

本案例将实现PWA的“添加到主屏幕”功能。默认情况下,浏览器会显示自带的安装提示,但体验不可控。我们的目标是:监听beforeinstallprompt事件,拦截浏览器默认安装提示,在页面中渲染自定义的“安装应用”按钮;用户点击按钮后,触发浏览器的安装流程,并在安装完成后隐藏按钮。

实现方案

核心逻辑分为三步:

  1. 监听beforeinstallprompt事件,阻止默认弹窗,保存事件对象并显示自定义按钮;
  2. 点击按钮时调用保存的prompt()方法,弹出浏览器原生安装确认框;
  3. 监听appinstalled事件,安装成功后隐藏按钮。

代码实现

创建index.html,内容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PWA安装示例</title>
    <link rel="manifest" href="#" aria-disabled="true" data-keke-missing-local-link="1" onclick="return false">
    <style>
        body { font-family: system-ui, sans-serif; max-width: 480px; margin: 0 auto; padding: 16px; }
        #install-btn {
            display: none;
            width: 100%;
            padding: 14px;
            font-size: 16px;
            background: #2563eb;
            color: #fff;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            margin-top: 20px;
        }
        #install-btn:active { background: #1d4ed8; }
    </style>
</head>
<body>
    <h3>PWA 添加到主屏幕</h3>
    <p>点击下方按钮,将应用安装到设备主屏幕。</p>
    <button id="install-btn">安装应用</button>

    <script>
        let deferredPrompt = null;
        const installBtn = document.getElementById('install-btn');

        // 1. 拦截浏览器默认安装提示
        window.addEventListener('beforeinstallprompt', (e) => {
            e.preventDefault();          // 阻止默认迷你弹窗
            deferredPrompt = e;          // 保存事件对象
            installBtn.style.display = 'block';  // 显示自定义按钮
        });

        // 2. 点击按钮触发安装
        installBtn.addEventListener('click', async () => {
            if (!deferredPrompt) return;
            deferredPrompt.prompt();     // 弹出原生安装确认框
            await deferredPrompt.userChoice;  // 等待用户选择
            deferredPrompt = null;       // 重置,防止重复安装
        });

        // 3. 安装成功后隐藏按钮
        window.addEventListener('appinstalled', () => {
            installBtn.style.display = 'none';
            deferredPrompt = null;
        });
    </script>
</body>
</html>

创建manifest.json(PWA安装的必要条件):

{
    "name": "PWA安装示例",
    "short_name": "安装示例",
    "start_url": "index.html",
    "display": "standalone",
    "background_color": "#ffffff",
    "theme_color": "#2563eb",
    "icons": [
        {
            "src": "icon-192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "icon-512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}
beforeinstallprompt 事件流程 浏览器 页面 (index.html) 用户 ① 触发事件 ② preventDefault ③ 显示按钮 ④ 点击按钮 ⑤ prompt() ⑥ 安装确认 ⑦ appinstalled 页面逻辑 用户操作 浏览器事件

落地与验证

运行方式:

  1. 准备两个图标文件icon-192.png和icon-512.png(任意PNG图片即可);
  2. 启动本地静态服务器(如npx serve或python -m http.server 8080),访问http://localhost:8080;
  3. 使用Chrome或Edge浏览器打开页面。

验证方法与判定标准:

  1. 首次访问时,页面不显示“安装应用”按钮,浏览器地址栏右侧可能出现安装图标(但不会弹出迷你弹窗);
  2. 在Chrome DevTools > Application > Manifest 中点击“Installability”可查看安装条件是否满足;
  3. 满足安装条件后(需要HTTPS或localhost,且manifest和图标有效),beforeinstallprompt事件触发,按钮显示;
  4. 点击按钮,浏览器弹出原生安装确认框;确认后应用安装到主屏幕/桌面,按钮自动隐藏;
  5. 若按钮未出现,请检查:是否通过localhost访问、manifest是否有效、图标是否192px以上且已提供。

预期行为说明:当安装条件满足时,按钮会从隐藏变为可见;点击后弹出系统安装确认框。安装成功后按钮消失。若浏览器不支持或条件不满足,按钮保持隐藏,这是符合预期的降级行为。