内容简介:PWA: Progressive Web Apps (渐进式Web应用程序)用PWA技术开发的网页, 如果将其保存在手机桌面上, 很难将其与手机上其它app区分开, 另外它还自带了缓存, 推送功能, 简直不要太爽, 下面介绍一下PWA网页的开发过程这一篇不介绍推送, 因为推送要服务端支持, 所以这里只创建一个静态项目就可以了
PWA: Progressive Web Apps (渐进式Web应用程序)
用PWA技术开发的网页, 如果将其保存在手机桌面上, 很难将其与手机上其它app区分开, 另外它还自带了缓存, 推送功能, 简直不要太爽, 下面介绍一下PWA网页的开发过程
创建项目
这一篇不介绍推送, 因为推送要服务端支持, 所以这里只创建一个静态项目就可以了
创建一个项目文件夹(pwa-demo) 在文件夹里创建 index.html
app.css
app.js
开发功能
在 index.html
里引入好css, js文件, 如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>CNodeJS PWA</title> <link rel="stylesheet" href="app.css" /> </head> <body> <!-- , "splash_pages": null --> <h1>CNodeJS</h1> <div id="main"></div> <script src="app.js"></script> </body> </html>
在 app.js
文件里写入请求接口的业务逻辑, 我这里用的是 cnodejs.org 的接口
const main = document.getElementById("main"); window.addEventListener("load", e => { loadTopics(); }); async function loadTopics() { const res = await fetch(`https://cnodejs.org/api/v1/topics`); const json = await res.json(); main.innerHTML = await json.data.map(createTopic).join("\n"); } function createTopic(topic) { return ` <div class="topic"> <img src="${topic.author.avatar_url}" alt=""/> <div class="title">${topic.title}</div> </div> `; }
原接文链: https://tomoya92.github.io/2019/05/23/pwa-cache/
给页面加上点css
.topic { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; padding-top: 10px; padding-bottom: 10px; border-bottom: 1px dashed #222; } .topic:first-child { padding-top: 0; } .topic:last-child { border-bottom: 0; } .topic img { width: 40px; height: 40px; border-radius: 10px; margin-right: 10px; } .topic .title { -webkit-box-flex: 1; -ms-flex: 1; flex: 1; font-weight: 500; font-size: 18px; }
打开 index.html
可以看到长这个样
添加Manifest
可以打开这个网站 https://app-manifest.firebaseapp.com/ , 把一些网页的信息和icon图标都填上, 点击生成, 就完事了
我在chrome里用这个网站生成的zip包里死活没有icons, 后来换成firefox就好了,不知道为啥
icon原图最好是512x512大小的
生成好之后, 把zip包解压, 将里面的文件复制到项目里
然后修改 index.html
文件内容, 在 head
里加上下面内容
<head> <link rel="manifest" href="manifest.json" /> </head>
打开浏览器控制台, 可以在 Application
选项里看到 Manifest 的信息
添加 serviceWorker
现在给网页加上缓存, 这样只要网页加载过一次, 就会把请求的数据都缓存下来, 在没有网络的环境下就可以继续查看了
在 app.js
里注册 serviceWorker
window.addEventListener("load", e => { loadTopics(); // 注册 serviceWorker if ("serviceWorker" in navigator) { try { navigator.serviceWorker.register("sw.js"); console.log("serviceWorker register success!"); } catch (error) { console.log("serviceWorker register failure!"); } } });
注册的 serviceWorker 文件名是 sw.js
所以要在项目根目录下创建 sw.js
文件
链原接文: https://tomoya92.github.io/2019/05/23/pwa-cache/
然后加上如下代码
self.addEventListener("install", async event => { console.log('sw install'); }); self.addEventListener("fetch", async event => { console.log('sw fetch'); });
运行网页可以看到控制台里有打印 sw install
字样, 表示 serviceWorker 注册成功了
添加缓存
如果没有缓存功能, 好像没法将网页保存在桌面上, 下面就来添加浏览器自带的缓存功能
首先将项目里一些静态文件缓存了, 比如 app.css
app.js
等
const staticAssets = ["./", "./app.css", "./app.js"]; self.addEventListener("install", async event => { const cache = await caches.open("static-assets"); cache.addAll(staticAssets); });
然后是对网络请求数据的缓存逻辑算是, 写法是固定的, 如下
self.addEventListener("fetch", async event => { const req = event.request; const url = new URL(req.url); if (url.origin === location.origin) { event.respondWith(cacheFirst(req)); } else { event.respondWith(networkFirst(req)); } }); async function cacheFirst(req) { const cachedResponse = await caches.match(req); return cachedResponse || fetch(req); } async function networkFirst(req) { const cache = await caches.open("topics-dynamic"); try { const res = await fetch(req); cache.put(req, res.clone()); return res; } catch (error) { return await cache.match(req); } }
再次运行网页, 这时候就可以将其保存在手机桌面上了
不过当保存的时候会发现没有icon, 然后我百度了一下, 还要在 index.html
里配置上下面这些东西
<head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>CNodeJS PWA</title> <link rel="stylesheet" href="app.css" /> <link rel="shortcut icon" href="images/icons/icon-72x72.png" type="image/x-icon" /> <!-- Specifying a Webpage Icon for Web Clip for Safari --> <link rel="apple-touch-icon" href="images/icons/icon-192x192.png" /> <!-- Specifying a Launch Screen Image for Safari <link rel="apple-touch-startup-image" href="assets/imgs/splash.png" />--> <!-- Hiding Safari User Interface Components --> <meta name="apple-mobile-web-app-capable" content="yes" /> <!-- Changing the Status Bar Appearance <meta name="apple-mobile-web-app-status-bar-style" content="black">--> <link rel="manifest" href="manifest.json" /> </head>
这样再用手机浏览器打开, 然后选择保存到桌面上,就有icon了, 保存成功后, 打开让数据请求接口加载完, 然后将手机网络关了, 刚打开的应用退出后台, 再次打开会发现数据照常加载了, 只不过是缓存里的
如果再给其加上推送功能, 是不是就跟手机上装的app没两样了, 下一篇来介绍一下serviceWorker的推送功能用法
原文链接:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM国际大学生程序设计竞赛亚洲区预选赛真题题解
郭炜 / 电子工业 / 2011-7 / 49.00元
ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest,简称ACM/ICPC)是世界上历史最悠久,规模最大、最具声望的程序设计竞赛,一直受到众多国际知名大学的重视,全球著名IT公司更是争相招募竞赛的优胜者。 该项赛事分为各大洲预选赛和全球总决赛两个阶段。北京大学多次在亚洲区预选赛中负责命题工作,是中国在ACM/ICPC命......一起来看看 《ACM国际大学生程序设计竞赛亚洲区预选赛真题题解》 这本书的介绍吧!