开始
这是一个纯练手的小项目,旨在练习使用PWA(Progressive Web Apps
)相关技术构建一个网络应用。
项目地址:https://github.com/bjw1234/ne...
预览地址:https://bjw1234.github.io/new...
手机端截屏:
主页面
详情页
PWA是什么?
PWA(Progressive Web Apps
)渐进式网络应用,结合了 Web 和 原生应用中最好功能的一种体验。对于首次访问的用户它是非常有利的, 用户可以直接在浏览器中进行访问,不需要安装应用。随着时间的推移当用户渐渐地和应用建立了联系,它将变得越来越强大。它能够快速地加载,即使在比较糟糕的网络环境下,能够推送相关消息, 也可以像原生应用那样添加至主屏,能够有全屏浏览的体验。
Service Worker
PWA中一个很重要的点就是利用Service Worker
拦截拦截客户端请求,如果请求命中缓存中的数据,则无需访问网络,直接返回。
注册Service Worker
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);
});
}
Service Worker详情
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);
});
}
解析URL
当用户在首页点击不同的新闻,需要跳转到新闻详情页。所以在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":"国内"
}
...
manifest.json配置
{
"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"
}
]
}
CSS实现多行文本超出省略号显示
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
是否支持webp格式的判断
// 在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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。