pwa应用进阶-区分AB面-添加安装按钮而且区分不同的系统和浏览器的各种情况 | 南锋

南锋

南奔万里空,脱死锋镝余

pwa应用进阶-区分AB面-添加安装按钮而且区分不同的系统和浏览器的各种情况

年前将cocosCreator导出的pwa包后,近两天又将pwa应用进行一些优化
主要优化点如下:
1、区分AB面,即用户直接通过浏览器访问链接和安装后点击桌面图标进来看到的内容不一样
2、添加了安装按钮,用户打开url后,需要手动点击安装按钮才能进行安装
3、区分了不同的系统和浏览器,在无法直接安装时,进行了弹窗提示

功能说明和注意事项

1、区分AB面,我这里的A面是index.html里面的内容,因为我的url直接指向的是这个文件。B面的内容可以使用另外一个链接,将链接地址写在manifest.json文件的start_url字段,这个字段其实就是通过桌面图标打开的路径。
2、区分了不同和系统和浏览器,这里主要是因为并不是所有的系统和浏览器都支持安装pwa。在点击按钮时会去判断系统和浏览器,如果支持安装,则进行安装,如果不支持,则进行弹窗提示。比如在苹果手机,使用chrome打开,会提示你使用safair浏览器打开。在safair打开后会提示你如何将应用添加到桌面。如下图片所示:

代码实现

index.html代码,其实主要的修改逻辑都在这里,其他的代码都和前面介绍的一样,不用怎么修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PWA 示例</title>
<meta name="theme-color" content="#ffffff">
<link rel="manifest" href="manifest.json">
<style>
#install-btn {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}

/* 提示图片样式 */
#ios-install-guide {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
justify-content: center;
align-items: center;
}

#ios-install-guide img {
width: 80%;
max-width: 400px;
border-radius: 10px;
}
</style>
<script>
let deferredPrompt;
let installBtn;

function isAndroid() {
return /Android/i.test(navigator.userAgent);
}

function isIOS() {
return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}

function isSafari() {
return isIOS() && navigator.userAgent.includes("Safari") && !navigator.userAgent.includes("CriOS") && !navigator.userAgent.includes("FxiOS");
}

function isPWAInstallable() {
return ('BeforeInstallPromptEvent' in window);
}

function isStandalone() {
return (window.matchMedia('(display-mode: standalone)').matches || navigator.standalone);
}

function isPC() {
return !isAndroid() && !isIOS();
}

document.addEventListener("DOMContentLoaded", () => {
installBtn = document.getElementById("install-btn");
const iosInstallGuide = document.getElementById("ios-install-guide");

window.addEventListener("beforeinstallprompt", (e) => {
e.preventDefault();
deferredPrompt = e;
});

installBtn.addEventListener("click", () => {
if (isAndroid()) {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
console.log(choiceResult.outcome === 'accepted' ? '用户接受了安装' : '用户拒绝了安装');
deferredPrompt = null;
});
} else {
alert("当前浏览器不支持 PWA 直接安装,请尝试使用 Chrome 或 Edge");
}
} else if (isIOS()) {
if (isSafari()) {
iosInstallGuide.style.display = "flex"; // 只有点击按钮后才显示图片
} else {
alert("请使用 Safari 浏览器,通过点击分享按钮并选择“添加到主屏幕”来安装 PWA 应用。");
}
} else if (isPC()) {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
console.log(choiceResult.outcome === 'accepted' ? '用户接受了安装' : '用户拒绝了安装');
deferredPrompt = null;
});
} else {
alert("当前浏览器不支持 PWA 直接安装,请尝试使用 Chrome 或 Edge");
}
}
});

// 点击图片后隐藏
iosInstallGuide.addEventListener("click", () => {
iosInstallGuide.style.display = "none";
});

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log("Service Worker 注册成功"))
.catch(err => console.error("Service Worker 注册失败", err));
}
});
</script>
</head>
<body>
<h1>A 界面</h1>
<p>安装 PWA 应用到设备。</p>
<button id="install-btn">安装 PWA 应用</button>

<!-- iOS 安装引导 -->
<div id="ios-install-guide">
<img src="ios-install-guide.png" alt="请点击 Safari 的分享按钮,然后选择‘添加到主屏幕’">
</div>
</body>
</html>

manifest.json代码展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"short_name": "MyPWA",
"name": "My Progressive Web App",
"start_url": "/client/test/pwa2/index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"icons": [
{
"src": "/client/test/pwa0206/icons/icon-192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/client/test/pwa0206/icons/icon-512x512.png",
"type": "image/png",
"sizes": "512x512"
}
]
}

service-worker.js代码展示

1
2
3
4
5
6
7
8
9
10
11
12
self.addEventListener('install', (event) => {
console.log("Service Worker 已安装");
self.skipWaiting();
});

self.addEventListener('activate', (event) => {
console.log("Service Worker 已激活");
});

self.addEventListener('fetch', (event) => {
console.log("拦截请求:", event.request.url);
});

此外,自己还需要准备2张icon图标,和一张ios-install-guide.png图片,用于在iOS设备上引导用户安装PWA应用。项目文件结构如下图所示:
项目结构

+