PWA(Progressive Web App)入門系列:(三)PWA關鍵技術Manifest
前言
前面說過,讓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
name: {string}
,用來描述應用的名稱,會顯示在各類提示的標題位置和啟動畫面中。
short_name
short_name: {string}
,用來描述應用的短名字。當應用的名字過長,在桌面圖示上無法全部顯示時,會用short_name
中定義的來顯示。
start_url
start_url: {string}
,用來描述當用戶從裝置的主螢幕點選圖示進入時,出現的第一個畫面。
- 如果設定為空字串,則會以manifest.js的地址做為URL
- 如果設定的URL開啟失敗,則和正常顯示的網頁開啟錯誤的樣式一下(可以通過後面講的ServiceWorker改善)
- 如果設定的URL與當前的專案不在一個域下,也不能正常顯示
start_url
必須在scope的作用域範圍內- 如果
start_url
是相對地址,那麼根路徑基於manifest
的路徑 - 如果
start_url
為絕對地址,則該地址將永遠以/
作為根路徑
scope
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
icons: {Array.<ImageObject>}
,用來設定Web App的圖示集合。
ImageObject
包含屬性:
src: {string}
,圖示的地址type {string}
,圖示的 mime 型別,可以不填寫。這個欄位會讓瀏覽器不使用定義型別外的圖示sizes {string}
,圖示的大小,用來表示width
xheight
,單位為px,如果圖示要適配多個尺寸,則第個尺寸間用空格分割,如12x12 24x24 100x100
。
sizes適配規則:
- 在PWA新增到桌面的時候,瀏覽器會適配最合適尺寸的圖示。瀏覽器首先會去找與顯示密度相匹配且尺寸調整到 48dp 螢幕密度的圖示,例如它會在 2 倍畫素的裝置上使用 96px,在 3 倍畫素的裝置上使用 144px。。
- 如果沒有找到任何符合的圖示,則會查詢與裝置特性匹配度最高的圖示。
- 如果匹配到的圖示路徑錯誤,將會顯示瀏覽器預設 icon。
需要注意的是,圖示中必須要有一張尺寸為144x144
的,圖示的 mime 型別為 image/png
的。
background_color
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
theme_color: {Color}
,定義和background_color
一樣的CSS顏色值,用於顯示Web App的主題色,顯示在banner位置。
display
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
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
dir: {string}
,設定文字的顯示方向。
- ltr
,文字顯示方向,左到右
- rtl
,文字顯示方向,右到左
- auto
,根據系統的方向顯示
related_applications
related_applications: {Array.<AppInfo>}
,用於定義對應的原生應用,類似應用安裝橫幅的形式去推廣、引流。
AppInfo
結構:
- platform: {string}
, 應用平臺
- id: {string}
應用id
如安卓可以這麼定義:
"related_applications": [
{
"platform": "play",
"id": "com.app.xxx"
}
]
prefer_related_applications
prefer_related_applications:{Boolean}
,用於設定只允許使用者安裝原生應用。
例項
下面寫一下相關的常用例項。
目錄結構
專案結構:
根路徑 /
|
|----manifest.json // 清單檔案
|
|----index.html
|
|----144x144.png // 圖示檔案
|
|----sw.js
因為瀏覽器要安裝manifest中的定義,需要一些其他的程式碼環境條件,以上目錄中,我們只討論manifest.json
檔案,其他檔案後面會做說明。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manifest</title>
<link rel="manifest" href="./manifest.json"> <!-- 引用manifest檔案 -->
</head>
<body>
<h1>Manifest Page</h1>
<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屬性,開啟的應用去除了瀏覽器的位址列。
注意
瀏覽器“新增到主螢幕”的提示是需要滿足下面條件才會顯示的:
- 需要manifest檔案
- manifest中需要定義
start_url
- 需要包含144x144的png圖示檔案
- 網站是通過Https訪問的
- 並且網站中執行ServiceWorker
- 使用者需要至少瀏覽過網站兩次,並且兩次的間隔大於5分鐘
- 如果修改了 manifest 的配置,已新增到主螢幕的名稱並不會改變,只有當用戶重新新增到桌面時,更改後的配置才會生效。但是在未來版本的 Chrome 瀏覽器將支援自動更新
關於上面提到的第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“觸發新增圖示到桌面的事件。
授權後即可新增到桌面
線上manifest驗證
除去本地除錯外,還可以通過線上清單驗證工具來實現驗證,例如:Web Manifest Validator
總結
到這裡,總結一下:
- manifest是一種簡單的JSON檔案,通過對屬性進行相應的配置,可以實現很多類Native的體驗
- 新增到主螢幕會觸發相應的事件,可以基於這些事件做相應的處理
- 除錯的時候,可以基於Chrome的開發者工具,或者通過線上的測試驗證工具
- https可以藉助github pages功能實現
部落格名稱:王樂平部落格
CSDN部落格地址:http://blog.csdn.net/lecepin