1. 程式人生 > >PWA(Progressive Web App)入門系列:(三)PWA關鍵技術Manifest

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},圖示的大小,用來表示widthxheight,單位為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"

其他的定義rgbahslhsla等顏色定義方式瀏覽器不支援,未設定時,背景色均顯示白色。

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-secondarylandscape-primary的180°方向
  • landscape,根據螢幕的方向,自動橫螢幕180°切換
  • portrait-primary,當視窗寬度小於高度時,當前應用處於“豎屏”狀態
  • portrait-secondaryportrait-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屬性,開啟的應用去除了瀏覽器的位址列。

注意

瀏覽器“新增到主螢幕”的提示是需要滿足下面條件才會顯示的:

  1. 需要manifest檔案
  2. manifest中需要定義start_url
  3. 需要包含144x144的png圖示檔案
  4. 網站是通過Https訪問的
  5. 並且網站中執行ServiceWorker
  6. 使用者需要至少瀏覽過網站兩次,並且兩次的間隔大於5分鐘
  7. 如果修改了 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

知識共享許可協議
本作品採用 知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。