前面说过,让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术,本章会详细说明manifest的实现,及各个参数的具体含义,还将了解如何定义Web App的启动图标、启动样式等。
manifest是一种简单的json数据风格的配置文件,通过对其相应的属性进行配置,才实现相应的功能,这里可以称manifest为WEB应用清单。WEB应用清单可以实现自定义启动画面、打开URL、设置界面颜色、设置桌面图标等等。
大概就是下面这样:
{
"short_name": "短名称",
"name": "这是一个完整名称",
"icons": [
{
"src": "144x144.png",
"type": "image/png",
"sizes": "144x144"
}
],
"background_color": "#2196f3",
"display": "standalone",
"start_url": "index.html"
}
好么manifest.js如何让浏览器去执行呢?
只需要用link
标记引用即可:
<link rel="manifest" href="manifest.js">
目前各大浏览器对manifest的支持程度:
下面对manifest涉及到的各个属性详细说一下。
name: {string}
,用来描述应用的名称,会显示在各类提示的标题位置和启动画面中。
short_name: {string}
,用来描述应用的短名字。当应用的名字过长,在桌面图标上无法全部显示时,会用short_name
中定义的来显示。
start_url: {string}
,用来描述当用户从设备的主屏幕点击图标进入时,出现的第一个画面。
start_url
必须在scope的作用域范围内start_url
是相对地址,那么根路径基于manifest
的路径start_url
为绝对地址,则该地址将永远以 /
作为根路径scope : {string}
,用来设置manifest
对于网站的作用范围。
下面列一下,scope
的作用范围及对start_url
的影响:
manifest的文件位置 | start_url | scope配置 | 计算好的scope | 计算好的start_url | 是否有效 |
---|---|---|---|---|---|
/inner/manifest.json | ./index.html | undefined | /inner/ | /index.html | 有效 |
/inner/manifest.json | ./index.html | ../ | / | /index.html | 有效 - 但作用域泄露到了更高层级 |
/inner/manifest.json | / | / | / | /index.html | 有效 - 但作用域泄露到了更高层级 |
/inner/manifest.json | / | undefined | /inner/ | / | 无效 - start url不在作用域范围内 |
/inner/manifest.json | ./inner/index.html | undefined | /inner/ | /inner/inner/index.html | 有效 - 但start url明显不符合预期 |
/manifest.json | ./inner/index.html | undefined | / | /inner/index.html | 有效 - 广作用域 |
/manifest.json | ./inner/index.html | inner | /inner/ | /inner/index.html | 有效 - 窄作用域 |
icons: {Array.
,用来设置Web App的图标集合。
ImageObject
包含属性:
src: {string}
,图标的地址type {string}
,图标的 mime 类型,可以不填写。这个字段会让浏览器不使用定义类型外的图标sizes {string}
,图标的大小,用来表示width
xheight
,单位为px,如果图标要适配多个尺寸,则第个尺寸间用空格分割,如12x12 24x24 100x100
。sizes适配规则:
需要注意的是,图标中必须要有一张尺寸为144x144
的,图标的 mime 类型为 image/png
的。
background_color: {Color}
,值为CSS的颜色值,用来设置Web App启动画面的背景颜色。
可以像正常写CSS颜色那样定义:
// 完整色值
"background_color": "#0000ff"
// 缩写
"background_color": "#00f"
// 预设色值
"background_color": "yellow"
// rgb
"background_color": "rgb(0, 255, 255)"
// transparent 背景色显示为黑色
"background_color": "transparent"
其他的定义rgba
、hsl
、hsla
等颜色定义方式浏览器不支持,未设置时,背景色均显示白色。
theme_color: {Color}
,定义和background_color
一样的CSS颜色值,用于显示Web App的主题色,显示在banner位置。
display: {string}
,用来指定 Web App 从主屏幕点击启动后的显示类型
显示类型 | 描述 | 降级显示类型 |
---|---|---|
fullscreen | 应用的显示界面将占满整个屏幕 | standalone |
standalone | 浏览器相关UI(如导航栏、工具栏等)将会被隐藏 | minimal-ui |
minimal-ui | 显示形式与standalone类似,浏览器相关UI会最小化为一个按钮,不同浏览器在实现上略有不同 | browser |
browser | 浏览器模式,与普通网页在浏览器中打开的显示一致 | (None) |
对于不同的显示样式,可以通过CSS的媒体查询进行设置:
@media all and (display-mode: fullscreen) {
div {
padding: 0;
}
}
@media all and (display-mode: standalone) {
div {
padding: 1px;
}
}
@media all and (display-mode: minimal-ui) {
div {
padding: 2px;
}
}
@media all and (display-mode: browser) {
div {
padding: 3px;
}
}
orientation: {string}
,Web App的在屏幕上的显示方向。
landscape-primary
,当视窗宽度大于高度时,当前应用处于“横屏”状态landscape-secondary
,landscape-primary
的180°方向landscape
,根据屏幕的方向,自动横屏幕180°切换portrait-primary
,当视窗宽度小于高度时,当前应用处于“竖屏”状态portrait-secondary
,portrait-primary
的180°方向portrait
,根据屏幕方向,自动竖屏180°切换natural
, 根据不同平台的规则,显示为当前平台的0°方向any
,任意方向切换dir: {string}
,设置文字的显示方向。
- ltr
,文本显示方向,左到右
- rtl
,文本显示方向,右到左
- auto
,根据系统的方向显示
related_applications: {Array.
,用于定义对应的原生应用,类似应用安装横幅的形式去推广、引流。
AppInfo
结构:
- platform: {string}
, 应用平台
- id: {string}
应用id
如安卓可以这么定义:
"related_applications": [
{
"platform": "play",
"id": "com.app.xxx"
}
]
prefer_related_applications:{Boolean}
,用于设置只允许用户安装原生应用。
下面写一下相关的常用实例。
项目结构:
根路径 /
|
|----manifest.json // 清单文件
|
|----index.html
|
|----144x144.png // 图标文件
|
|----sw.js
因为浏览器要安装manifest中的定义,需要一些其他的代码环境条件,以上目录中,我们只讨论manifest.json
文件,其他文件后面会做说明。
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manifesttitle>
<link rel="manifest" href="./manifest.json">
head>
<body>
<h1>Manifest Pageh1>
<script>
// 此处代码 后面相关章节会去说明
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw.js')
.then(function(registration) {})
.catch(function(err) {})
})
}
script>
body>
html>
sw.js
// 此处代码 后面相关章节会去说明
var cacheName = 'helloWorld'
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll([
'index.html'
]))
)
})
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
}
return fetch(event.request);
})
)
})
144x144.png
manifest.js
{
"short_name": "短名称",
"name": "这是一个完整名称",
"icons": [
{
"src": "144x144.png",
"type": "image/png",
"sizes": "144x144"
}
],
"display": "standalone",
"start_url": "index.html"
}
按照上面方式配置,在移动端Chrome上访问,效果如下:
浏览器会提示一个“添加到主屏幕”的提示。提示的标题显示的是在manifest中定义的name,当点击时,就会将应用添加到桌面:
桌面图标上显示的文本为manifest中定义的short_name。
点击应用图标,打开应用:
可以看到根据设置的display属性,打开的应用去除了浏览器的地址栏。
浏览器“添加到主屏幕”的提示是需要满足下面条件才会显示的:
start_url
关于上面提到的第4点,我们可以建立一个https网站或者可以直接用github的pages服务来实现。
关于第6点,是为了防止每次打开网址都有这个提示,对用户造成较差的体验。
"theme_color": "red"
给主题色设置个红色:
可以发现App的header上已经变成了设置的红色。
启动界面是由icon、background_color和name构成的。
"background_color": "#2196f3"
效果:
icon也会根据屏幕的尺寸,浏览器来适配最佳的图标。
当执行”添加到主屏幕“的操作时,内部会触发相应的事件beforinstallprompt
。可以利用这个事件做一些事情,例如App判断流量入口:
window.addEventListener('beforeinstallprompt', function(e) {
e.userChoice.then(function (result){
if (result.outcome === 'dismissed'){
// 发送数据进行分析
} else {
// 发送数据进行分析
}
})
})
事件中的userChoice
对象用来返回用户的选择信息,处理是基于Promise的,这个后面章节会详说。
上面是为了实现真是效果,所以在真是移动端上实现的。其实在测试的时候,是可以通过Chrome的开发者工具来测试的。
首先,打开上一章里下载的”WebServer for Chrome”本地服务器工具,并把项目加下到里面,然后开始服务
然后,在Chrome浏览器中访问”Web Server URL(s)“下的地址http://127.0.0.1:8887
然后,打开开发者工具,打开Application选项卡,选择Manifest,就可以后到配置的信息了。
并可以通过点击”Add to homescreen“触发添加图标到桌面的事件。
授权后即可添加到桌面
除去本地调试外,还可以通过在线清单验证工具来实现验证,例如:Web Manifest Validator
到这里,总结一下:
博客名称:王乐平博客
CSDN博客地址:http://blog.csdn.net/lecepin