這是一個純練手的小項目,旨在練習使用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; }