摘要:根據來完成主線程的消息推送重點推薦使用在內部細節中,處理了兼容性和權限請求的問題,這里我們具體落實到場景當中。
本文主要介紹一個 pwa 很方便的庫,適合在新手上手相關的 pwa 功能。
該庫是應對當前 Google 提出的 PWA 概念而寫的。以鏈式 API 來完成 PWA 相關的操作。
(如果感覺閱讀體驗不佳,可以參考 web-pwa)
安裝npm install web-pwa // 或者使用 yarn yarn add web-pwaDEMO
首先說明一下,我們要完成的目標:
注冊 sw
添加 app.js 的緩存
實現推送,并在用戶點擊后關閉,然后聚焦當前頁面
整個代碼如下:
import SW,{Notify,WebCaches} from "web-pwa"; window.onload = function(){ SW.register("sw.js"); var tableName = "prefetch-cache-v1"; WebCaches.table(tableName).addRow("/app.js") .then(res=>{ // res: 成功 }) Notify.request() // 請求推送權限 .then(permission=>{ // 用戶同意 Notify.show("villianhr","Hello Pwa") .onclick(event=>{ event.close(); // 關閉當前 Notification Notify.focus(); // 聚焦窗口 }) }) }使用
基本使用可以分為三塊:
SW: 主要處理主線程 JS Service Worker 的相關行為。例如:注冊,發送消息等
WebCaches: 用來處理 CacheStorage 緩存的相關操作。
Notify: 根據 new Notification() 來完成主線程 JS 的消息推送
import SW,{WebCaches,Notify} from "web-pwa";
(重點推薦使用 WebCaches)
在內部細節中,處理了兼容性和權限請求的問題,這里我們具體落實到場景當中。
SW 原意是 Service Worker。如果大家還不熟悉,推薦可以參考:Service Worker 全面進階。
權限申請SW.register("sw.js") .then(reg=>{ })
它返回的是 Promise 對象。
銷毀 Service WorkerSW.unregister().then(res=>{ if(res)console.log("unregisteration, done!"); })
它返回的是 Promise 對象。
Service Worker 更新SW.update();消息通信
我們了解 Service Worker 是繼承 Web Worker。在 Web Worker 中,我們可以使用 postMessage 進行通信,那么在 SW(Service Worker)中同樣是可以的。
SW.postMessage("a new message send to Service Worker");
如果你想接受此次 SW 回復的信息,可以直接加上 Promise 的寫法。
// 接收 SW 回復的信息 SW.postMessage("a new message send to Service Worker") .then(reply=>{ // doSth }) // SW 回復信息 self.addEventListener("message", function(event){ console.log("SW Received Message: " + event.data); event.ports[0].postMessage("SW Says "Hello back!""); });
另外,SW 還可以通過 clients 掛載的 postMessage 向 client 發送信息。如果有這種需求,可以直接監聽 message 事件。
SW.onmessage(event=>{ // 接收 SW 發送的消息 // event.data })推送訂閱
當你想要使用 Push 相關的內容時,可以調用 Notify.subscribe(route,key) 方法。如果,你不是很理解 Web Push 的概念,可以參考: Web Push 講解
// 下面的 key 根據自己生成進行替換 SW.subscribe("/subscription","BPLISiRYgXzzLY_-mKahMBdYPeRZU-8bFVzgJMcDuthMxD08v0cEfc9krx6pG5VGOC31oX_QEuOSgU5CYJqpzf0");WebCaches
首先這里有兩個概念,一個是 table(表),一個是 row(行)。每一個網站緩存可以有多個表,這完全取決于你自己的結構。該庫是 one-off 形式,即,不能使用變量名來緩存表。例如:
var table = WebCaches.table("v1"); table.open(); // 正常執行沒問題 table.open(); // 第二次使用無效
后面會介紹一種簡便的方法進行簡寫。
緩存處理主要分為兩塊:
table
addRow: 添加行記錄
delete: 刪除表
copy: 復制整個表
rename: 重命名整個表
open: 打開表
row
get: 查詢行
delete: 刪除行
update: 更新行
tabletable 本身就是一個函數,構造格式為:
table(cachesName): 打開某個具體的表
@param cachesName[String]: 具體打開的表名
構造函數為:
open(): 執行打開操作
@return: promise
WebCaches.table("demo-v1").open() .then(cache=>{})
向表中添加具體的緩存行,添加方式有三種:
addRow(request)
@param request: 可以為 url 或者通過 new Request(url) 實例化得來的。
addRow([request1,request2,...])
@param Array: 里面就是 url/request 的數組。
addRow(request,response)
@param request: 和上面一樣,沒啥區別
@param response: 需要存儲的結構。一般是通過 new Response(res) 生成,或者直接通過 fetch().then(response=>{}) 獲得的。
重命名的格式為:
rename(newName)
@param newName[String]: 表的新名字
@return Promise
WebCaches.table("old-v1").rename("new-v2") .then(res=>{ // success }) .catch(err=>{ // fail })
復制表的格式為:
copyTo(targetTable)
@param targetTable[String]: 指定的表名
@return Promise
// 將 A 表復制給 B WebCaches.table("A").copyTo("B") .then(res=>{ // success }) .catch(err=>{ // fail })
格式為:
delete()
@return: Promise
WebCaches.table("A").delete() .then(res=>{ // success }) .catch(err=>{ // fail })row
row 本身也是一個函數:
row(request)
@param request[Request||String]: 該參數可以為 request,或者 pathname(注意不能帶上 origin)。當為 request 時,是直接匹配對應的行記錄,而為 pathname 時,則是使用 path-to-regexp 的格式,可以匹配多個或者模糊匹配。
// 只匹配 js 文件 WebCaches.table(tableName).row("/*.js") .get().then(res=>{ console.log(res); })
通過 request 匹配:
var js = new Request("/app.js"); Caches.table(tableName).row(js) .get().then(res=>{ console.log(res); })
如果每次都 WebCaches.table.row 這樣調用,會讓人覺得比較冗長,那么有沒有什么好的辦法解決呢?這里提供了一個工具函數 clone 用來生成可重復使用的對象。
// 提取 table var table_v1 = WebCaches.clone("v1"); table_v1().open(); // first,OK table_v1().open(); // second,OK
然后,可以提取 row
var table_row = WebCaches.clone("v1","/*.js"); table_row().get(); // first, OK table_row().get(); // second, OK
// 刪除所有 js 文件 WebCaches.table(tableName).row("/*.js") .delete() .then(()=>{ // success }) .catch(err=>{ // fail })
fetch("/") .then(res=>{ // 更新根目錄文件 WebCaches.table(tableName).row("/") .update(res) .then(()=>{ WebCaches.table(tableName).row("/").get() .then(console.log.bind(console)) }) })Notify
Notify 提供了 Notification 相關的 API。其主打的是鏈式調用,不需要過多的關注 Notification 內部細節。
權限申請notify.request() .then(permission=>{ // permission === "granted" // permission === "denied" // permission === "default" })消息推送
使用消息推送的時候,可以不用嵌套在 request() 里面,它內部已經做了權限的處理。
// 純文字版 Notify.show("demo","this is a demo") // 帶 Icon Notify.show("demo","this is a demo","demo.png")推送后自動關閉
Notify.show("demo","this is a demo") .hide(3000); // 3s 后自動關閉推送點擊
Notify.show("demo","this is a demo") .onclick(e=>{ e.target.close(); });
Notify 還提供了其它的事件監聽
onclick
onclose
onshow
onerror
上面這些方法都可以進行鏈式調用。
Notify.show("demo","this is a demo") .onclick(event=>{}) .onclose(event=>{}) .onshow(event=>{})
用戶點擊推送這一行為,我們可以加上額外的處理,例如,打開頁面,聚焦頁面等。
Notify.show("demo","this is a demo") .onclick(event=>{ event.target.close(); // 聚焦頁面 Notify.focus(); // 打開新的頁面 Notify.open("https://www.villainhr.com"); })License
MIT
Authorauthor: villainhr
email: villainthr@gmail.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/61832.html
閱讀 1131·2021-11-24 10:21
閱讀 2570·2021-11-19 11:35
閱讀 1671·2019-08-30 15:55
閱讀 1298·2019-08-30 15:54
閱讀 1200·2019-08-30 15:53
閱讀 3511·2019-08-29 17:21
閱讀 3312·2019-08-29 16:12
閱讀 3422·2019-08-29 15:23