H5的离线存储

5 篇文章 0 订阅
包含以下内容:
1.搭建一个简单的离线应用
2. 离线之后资源的更新------Service Worker
3. localStorage与sessionStorage
4. indexDB实现便签管理

1.搭建一个简单的离线应用
用户在没有网络的情况下也可以进行访问。
HTML5离线功能包含离线资源缓存、在线状态监测、本地数据存储等方面的内容。
  • 离线资源缓存:
通过浏览器机制将在线资源缓存到本地,当用户离线访问应用程序时,这些资源文件自动从本 地加载,从而让用户可以正常使用应用程序。
  • 在线状态监测:
有些应用需要跟服务器做一些数据的交互,应用开发者需要知道浏览器是否处于在线状态, HTML 5中提供了在线状态的监测。
  • 本地数据存储:
当应用程序处于离线状态时,程序需要把用户产生的数据存储到本地,以便在线时同步到服务器上。为此, HTML 5提供了多种本地存储机制。
Web应用对比普通的Web应用多了一个描述文件,该文件用来列出需要缓存和永不缓存,以备离线时使用。描述文件扩展名“.manifest”或“ .appcache”,推荐使用后者。描述文件的mime-type类型为 “text/cache-manifest”,且 必须使用utf-8编码
offline.appcache如下:
CACHE MANIFEST
#cache之后的资源都会被缓存
CACHE:
main.html
style.css
main.js
#network之后的资源不会被缓存,总是从线上获取,
NETWORK:
account/

实现离线,随手记代码。
1. main.html:
<html>
<head>
<meta charset="utf-8">
<title>随手记</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>随手记--实时保存</h2>
<div>
<textarea id="content" cols="100" rows="20"></textarea>
</div>
<script src="main.js"></script>
</body>
</html>

2.要想实现离线化,只需将main.html与manifest描述文件关联起来即可
<html manifest= "./offline.appcache" >

3. // 获取记录内容的文本域
var el = document.querySelector('#content');
// 为文本域DOM节点添加blur事件
el.addEventListener('blur', function(){
// 获取文本域的内容
var data = el.innerHTML;
// 如果是在线状态,就直接保存到服务器
if( navigator.onLine){
saveOnline(data);
}else{
// 如果是离线状态,则保存到本地
localStorage.setItem('data', data);
}
});
// 监听上线事件
window.online = function(){
// 从本地存储获取数据
var data = localStorage.getItem('data');
if(!!data){
// 如果数据存在,则保存到服务器
saveOnline(data);
// 同时,清空本地的存储
localStorage.removeItem('data');
}
};
// 保存内容的具体代码
function saveOnline(data){
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8000/savedata');
xhr.send('data='+data);
}

2. 离线之后资源的更新------Service Worker
Application Cache控制缓存,已经被Service Worker取代。
https://www.w3.org/TR/service-workers/
主要提供4类功能:
  • 后台消息传递
  • 网络代理
  • 离线缓存
  • 消息推送
1. 在main.js中添加如下代码:
// 注册 service worker
navigator.serviceWorker.register(' sw.js').then(function(registration) {
console.log('Service Worker 注册成功');
}).catch(function (err) {
console.log('Servcie Worker 注册失败:'+err);
});
2. sw.js
// 需要缓存的资源列表
var cacheFiles = [
'style.css',
'main.js'
];
// 在install事件里缓存资源
self.addEventListener('install', function (evt) {
evt.waitUntil(
caches.open('mycache').then(function (cache) {
return cache.addAll(cacheFiles);
})
);
});
以上方式是手动实现静态文件更新,也可通过与服务器通信决定何时缓存和更新。

3. localStorage与sessionStorage
h5之前WEB应用的存储方案一般通过Cookie实现。
Cookie有如下弊端
  • 大小受限,限制4kb
  • 消耗性能,当前域下所有http请求都会携带这些Cookie
h5的本地存储为每个网站提供 5MB大小空间,对于文本存储已经能够满足业务大部分需求。
  • localStorage:一直存储在本地,直到手动清除
  • sessionStorage:页面关闭则缓存清空
用法1:
// 存储数据
localStorage.setItem('key', '需要存储的数据');
// 获取数据
var value = localStorage.getItem('key');
// 删除数据
localStorage.removeItem('key');
用法2---使用索引:
// 存储数据
localStorage['key1'] = 'value1';
localStorage.key2 = 'value2';
// 获取数据
var value1 = localStorage['key1'];
var value2 = localStorage.key2;
用法3---遍历和清空:
// 遍历所有存储的数据
for(var i=0;i< localStorage.length ;i++){
// 获取key
var key = localStorage.key(i);
// 获取value
var value = localStorage.getItem(key);
// 打印到控制台
console.log(key, value);
}
// 清空所有数据
localStorage.clear();

实例:随手记本地存储
// 获取记录内容的文本域
var el = document.querySelector('#content');
// 页面载入时,从本地获取存储的数据
el.value = localStorage.getItem('data') || '';
// 为文本域DOM节点添加blur事件
el.addEventListener('blur', function(){
// 获取文本域的内容
var data = el.value;
// 保存到本地
localStorage.setItem('data', data);
});
注意:
本地存储只支持存储字符串类型数据,若要存储JSON数据,需要先将数据转换成字符串。

4. indexDB实现便签管理
indexDB用于存储大量结构化的数据,并且使用基于索引的高效API检索。
html文件如下:
<body>
<!--创建一个便签容器-->
<div class="notes">
<!--添加按钮-->
<div class="add">
<p class="ic_add">+</p>
<p>添加便签</p>
</div>
</div>
<!--为了简化代码,基于jQuery开发-->
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<!--自己封装的操作indexedDB的帮助类-->
<script src="indexeddb.js"></script>
<script>
/ / 预先定义每一个便签的HTML代码
var divstr = '<div class="note"><a class="close">X</a><textarea></textarea></div>';
// 实例化一个便签数据库、数据表
var db = new LocalDB('db1', 'notes');
// 打开数据库
db.open(function(){
// 页面初始化时,获取所有已有便签
db.getAll(function(data){
var div = $(divstr);
div.data('id', data.id);
div.find('textarea').val(data.content);
// 将便签插入到添加按钮前边
div.insertBefore(add);
});
});
// 为添加按钮注册点击事件
var add = $('.add').on('click', function(){
var div = $(divstr);
div.insertBefore(add);
// 添加一条空数据到数据库
db.set({content:''}, function(id){
// 将数据库生成的自增id赋值到便签上
div.data('id', id);
});
});
// 监听所有便签编辑域的焦点事件
$('.notes').on('blur', 'textarea', function(){
var div = $(this).parent();
// 获取该便签的id和内容
var data = { id: div.data('id'), content: $(this).val() };
// 写入数据库
db.set(data);
})
// 监听所有关闭按钮的点击事件
.on('click', '.close', function(){
if(confirm('确定删除此便签吗?')){
var div = $(this).parent();
// 删除这条便签数据
db.remove(div.data('id'));
// 删除便签DOM元素
div.remove();
}
});
</script>
</body>

封装好的indexDB操作逻辑indexeddb.js
// 声明一个数据库操作的构造函数
function LocalDB(dbName, tableName) {
this.dbName = dbName;
this.tableName = tableName;
this.db = null;
}
// 在原型链上注册open方法,完成打开数据库的操作
LocalDB.prototype.open = function (callback) {
var _this = this;
// 执行打开数据库的动作
var request = window.indexedDB.open(_this.dbName);
// 打开成功后的回调
request.onsuccess = function (event) {
// 获取打开结果:数据库实例
_this.db = request.result;
// 如果调用方有回调函数的话,就执行回调函数
callback && callback();
};
// 第一次创建数据库时触发该事件
request.onupgradeneeded = function (event) {
// 获取数据库实例
var db = request.result;
// 检查是否存在指定的表
if (!db.objectStoreNames.contains(_this.tableName)) {
// 如果不存在,则创建,并指定一个自增的id作为查询依据
db.createObjectStore(_this.tableName, {
keyPath: "id",
autoIncrement: true
});
}
};
}
// 获取数据表的实例
LocalDB.prototype.getStore = function () {
var transaction = this.db.transaction(this.tableName, 'readwrite');
var objStore = transaction.objectStore(this.tableName);
return objStore;
}
// 保存一条数据:支持添加和修改
LocalDB.prototype.set = function (data, callback) {
var objStore = this.getStore();
var request = data.id ? objStore.put(data) : objStore.add(data);
request.onsuccess = function (event) {
callback && callback(event.target.result);
};
}
// 获取一条数据
LocalDB.prototype.get = function (id, callback) {
var objStore = this.getStore();
var request = objStore.get(id);
request.onsuccess = function (event) {
callback && callback(event.target.result);
}
}
// 获取表中所有的数据
LocalDB.prototype.getAll = function (callback) {
var objStore = this.getStore();
// 打开数据游标
var request = objStore.openCursor();
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
// 如果游标存在,执行回调并传入当前数据行
callback && callback(cursor.value);
// 继续下一行数据
cursor.continue();
}
}
}
// 删除一条数据
LocalDB.prototype.remove = function (id) {
var objStore = this.getStore();
objStore.delete(id);
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值