这是一个纯练手的小项目,旨在练习使用PWA(Progressive Web Apps
)相关技术构建一个网络应用。css
项目地址:https://github.com/bjw1234/ne...html
预览地址:https://bjw1234.github.io/new...git
手机端截屏:github
主页面web
详情页shell
PWA(Progressive Web Apps
)渐进式网络应用,结合了 Web 和 原生应用中最好功能的一种体验。对于首次访问的用户它是很是有利的, 用户能够直接在浏览器中进行访问,不须要安装应用。随着时间的推移当用户渐渐地和应用创建了联系,它将变得愈来愈强大。它可以快速地加载,即便在比较糟糕的网络环境下,可以推送相关消息, 也能够像原生应用那样添加至主屏,可以有全屏浏览的体验。json
PWA中一个很重要的点就是利用Service Worker
拦截拦截客户端请求,若是请求命中缓存中的数据,则无需访问网络,直接返回。canvas
if('serviceWorker' in navigator){ navigator.serviceWorker.register('./news_sw.js').then(reg => { console.log('ServiceWorker registration successful with scope:' + reg.scope); }).catch(err => { console.log('ServiceWorker registration fail:',err); }); }
news_sw.js
,在这个文件中咱们须要去监听三件事情,Service Worker的安装,激活以及fetch
事件。浏览器
// 安装事件,在这里将一些初始化或者`app shell`资源加入缓存列表 self.addEventListener('install', event => { event.waitUntil( // xxx ); }); // 激活事件,在这个函数中处理资源的更新 self.addEventListener('activate', event => { event.waitUntil(( //xxx ); }); // fetch事件,在这个函数中拦截并处理用户的请求 self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request,{ ignoreSearch: true }).then( response => { if(response){ // 缓存命中直接返回 } // 向服务器请求资源 // 出错则返回 // response ok // 添加到缓存列表 }); ); });
function requestData(url) { fetch(url,{ method:'GET' }).then(result => { if(result){ return result.json(); } }).then(data => { console.log(data); buildWebPage(data.latestNews); }); }
当用户在首页点击不一样的新闻,须要跳转到新闻详情页。因此在article.js
中去解析URL判断给用户呈现什么内容。缓存
// 解析url function queryParameter(url){ let obj = {}; url.replace(/([^?&=]+)=([^?&=]+)/g,($0,$1,$2) => { obj[$1] = $2; }); return obj; } // 获取地址栏的url let param = queryParameter(document.location.href);
模拟来自服务器端的json数据。
{ "id": 0, "image":"./images/0.jpg", "title": "中方回应马来西亚将取消新隆高铁项目", "desc": "有记者问:据报道,马来西亚总理昨天宣布将取消新隆高铁项目......", "time":"两分钟前", "read":"2344评", "type":"国内" } ...
{ "name": "news web app", "short_name": "hello news", "start_url": "./index.html", "theme_color": "#00ff8b", "background_color": "#00ff8b", "display": "standalone", "icons": [ { "src": "./images/news-144.png", "sizes": "144X144", "type": "image/png" }, { "src": "./images/news-192.png", "sizes": "192X192", "type": "image/png" } ] }
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
// 在serviceWorker中拦截请求 self.addEventListener('fetch',event => { if(/\.jpg$|\.png$/.test(event.request.url)){ let supportWebp = false; // 判断是否支持webp文件 if(event.request.headers.has('accept')){ supportWebp = event.request.headers.get('accept').includes('webp'); } if(supportWebp){ var req = event.request.clone(); var returnUrl = 'http://localhost/sunset.jpg'; console.log(returnUrl); event.respondWith( fetch(returnUrl,{ mode:'no-cors' }) ); } } }); // 在window中判断 function isSupportWebp(){ var isSWebp = !![].map && document.createElement('canvas').toDataURL('image/webp'). indexOf('data:image/webp') == 0; return isSWebp; }