indexedDB入门
localforage
- localStorage局限性:存储容量限制,仅支持字符串,如果是存对象还需要将使用JSON.stringify和JSON.parse方法互相转换;读取都是同步的。大多数情况ok。但如果存储数据比较大,例如一张重要图片base64格式存储了,再读可能会有可感知的延迟时间。
- localforage 是一个js库,通过简单类似locaStorage的异步存储来改进你的 Web 应用程序的离线体验。它能存储多种类型的数据,而不仅仅是字符串。localforage 有一个优雅降级策略,若浏览器不支持 IndexedDB 或 WebSQL,则使用 localStorage;
- API:
indexedDB
- IndexedDB数据库使用key-value键值对储存数据;任何操作都发生在事务(transaction)中,indexedDB API提供了索引(indexes), 表(tables), 指针(cursors)等, 但是所有这些必须是依赖于某种事务的;不使用sql,而是通过索引(index)所产生的指针(cursor)来完成查询操作,从而使你可以遍历到结果;和大多数web存储解决方案相同,indexedDB也遵从同源协议;indexedDB在结果准备好之后通过DOM事件通知用户(success,error);indexedDB是websql的替代品,是非关系型数据库(nosql)的一种;
- indexedDB数据库必须包含名字和版本
- 使用indexedDB的基本模式:
- 打开数据库并且开始一个事务。
- 创建一个 object store。
- 构建一个请求来执行一些数据库操作,像增加或提取数据等。
- 通过监听正确类型的 DOM 事件以等待操作完成。
- 在操作结果上进行一些操作(可以在 request 对象中找到)。
- 打开indexedDB数据库
var dbOpenRequest = window.indexedDB.open(dbName, version);
- 创建数据库的主键和字段
// onupgradeneeded用于数据库首次创建版本,或者window.indexedDB.open传递的新版本(版本要比现在的高)
dbOpenRequest.onupgradeneeded = function(event) {
var db = event.target.result;
db.onerror = function(event) {
console.log('数据库打开失败');
};
// 创建一个数据库存储对象
var objectStore = db.createObjectStore(dbname, {
keyPath: 'id',
autoIncrement: true
});
// 定义存储对象的数据项
objectStore.createIndex(indexName, keyPath, {unique: true});
} - 事务(可以理解为对数据库的操作,而且专指一个序列上的操作)
原子性(Atomicity):事务中的所有操作作为一个整体提交或回滚。
一致性(Consistemcy):事物完成时,数据必须是一致的,以保证数据的无损。
隔离性(Isolation):对数据进行修改的多个事务是彼此隔离的。
持久性(Durability):事务完成之后,它对于系统的影响是永久的,该修改即使出现系统故障也将一直保留。var transaction = db.transaction([dbName], 'readwrite');
// 打开已存储的数据对象
var objectStore = transaction.objectStore(dbName); // 增、删、清空、改
var objectStoreRequest = objectStore.add();
var objectStoreRequest = objectStore.delete();
var objectStoreRequest = objectStore.clear();
var objectStoreRequest = objectStore.put(); // 获取存储的对应键的存储对象
var objectStoreRequest = objectStore.get(id); objectStoreRequest.onsuccess = function(){
// 成功处理
} - 游标
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(cusor)
// 继续下一个游标项
cursor.continue();
}
else {
alert("No more entries!");
}
}; - 索引
var index = objectStore.index("name");
index.get(name).onsuccess = function(event) {
console.log(event.target.result)
}; index.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// cursor.key 是一个 name, 然后 cursor.value 是整个对象。
cursor.continue();
}
}; index.openKeyCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// cursor.key 是一个 name, 然后 cursor.value 是那个主键。
// 没有办法可以得到存储对象的其余部分。
cursor.continue();
}
}; // openCursor(val)可以传参数(具体的key或者范围) - 如果是浏览器主窗体线程开发,同时存储数据结构简单,例如,就存个
true/false,显然localStorage上上选;如果数据结构比较复杂,同时对浏览器兼容性没什么要求,可以考虑使用indexedDB;如果是在Service Workers中开发应用,只能使用indexedDB数据存储。 - 局限性:
全球多种语言混合存储。国际化支持不好。需要自己处理和服务器端数据库同步。你得自己写同步代码
全文搜索
ps(在以下情况下,数据库可能被清除):
用户请求清除数据
浏览器处于隐私模式。最后退出浏览器的时候,数据会被清除
硬盘等存储设备的容量到限
不正确的
不完整的改变 - 写一个demo(参考HTML5 indexedDB前端本地存储数据库实例教程),增加了查询,清空等功能;
<!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>Document</title>
</head>
<body>
<form id="form">
<p>项目名称:<input required name="name" autocomplete="off" required></p>
<p>开始时间:<input type="date" value="2017-07-16" name="begin" required></p>
<p>预计结束:<input type="date" value="2057-07-16" name="end" required></p>
<p>参与人员:<input name="person" placeholder="多人空格分隔" required autocomplete="off"></p>
<p>补充说明:<textarea rows="5" placeholder="非必填" name="remark"></textarea></p>
<p><input type="submit" value="确定创建"></p>
</form>
<p>查询:<input type='text' required id='searchVal'><button id='search'>Search</button></p>
<button id='clear'>clear</button> <div id="result" class="result">
<table>
<thead>
<tr>
<th>项目名称</th>
<th>开始时间</th>
<th>结束时间</th>
<th>参与人员</th>
<th>补充说明</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
<div id="status" class="status">加载中...</div>
</div> <!-- 列表数据模板 -->
<script id="tplList" type="text/template">
<tr>
<td data-key="name" data-id="$id$" contenteditable="plaintext-only">$name$</td>
<td data-key="begin" data-id="$id$" contenteditable="plaintext-only">$begin$</td>
<td data-key="end" data-id="$id$" contenteditable="plaintext-only">$end$</td>
<td data-key="person" data-id="$id$" contenteditable="plaintext-only">$person$</td>
<td data-key="remark" data-id="$id$" contenteditable="plaintext-only">$remark$</td>
<td><a href="javascript:" role="button" class="jsListDel" data-id="$id$">删除</a></td>
</tr>
</script>
<script>
(function () {
// 元素们
var eleForm = document.querySelector('#form');
var eleTbody = document.querySelector('#result tbody');
var eleStatus = document.getElementById('status');
var search = document.getElementById('search');
var searchVal = document.getElementById('searchVal');
var clear = document.getElementById('clear');
// 模板字符内容
var strTplList = document.getElementById('tplList').innerHTML; var logError = function (error) {
eleStatus.style.display = 'block';
eleStatus.innerHTML = '<span class="error">'+ error +'</span>';
}, logInfo = function (info) {
eleStatus.style.display = 'block';
eleStatus.innerHTML = '<span class="info">'+ info + '</span>';
}; // 简易模板方法
String.prototype.temp = function(obj) {
return this.replace(/\$\w+\$/gi, function(matchs) {
return obj[matchs.replace(/\$/g, "")] || '';
});
}; // 本演示使用的数据库名称
var dbName = 'project';
// 版本
var version = 1;
// 数据库数据结果
var db; // 打开数据库
var DBOpenRequest = window.indexedDB.open(dbName, version); // 如果数据库打开失败
DBOpenRequest.onerror = function(event) {
logError('数据库打开失败');
}; DBOpenRequest.onsuccess = function(event) {
// 存储数据结果
db = DBOpenRequest.result; // 显示数据
method.show();
}; // 下面事情执行于:数据库首次创建版本,或者window.indexedDB.open传递的新版本(版本数值要比现在的高)
DBOpenRequest.onupgradeneeded = function(event) {
var db = event.target.result; db.onerror = function(event) {
logError('数据库打开失败');
}; // 创建一个数据库存储对象
var objectStore = db.createObjectStore(dbName, {
keyPath: 'id',
autoIncrement: true
}); // 定义存储对象的数据项
objectStore.createIndex('id', 'id', {
unique: true
});
objectStore.createIndex('name', 'name');
objectStore.createIndex('begin', 'begin');
objectStore.createIndex('end', 'end');
objectStore.createIndex('person', 'person');
objectStore.createIndex('remark', 'remark');
}; search.addEventListener('click', function(){
method.search(searchVal.value);
})
clear.addEventListener('click', function(){
method.clear();
}) var method = {
add: function (newItem) {
var transaction = db.transaction([dbName], "readwrite");
// 打开已经存储的数据对象
var objectStore = transaction.objectStore(dbName);
// 添加到数据对象中
var objectStoreRequest = objectStore.add(newItem);
objectStoreRequest.onsuccess = function(event) {
method.show();
};
},
edit: function (id, data) {
// 编辑数据
var transaction = db.transaction([dbName], "readwrite");
// 打开已经存储的数据对象
var objectStore = transaction.objectStore(dbName);
// 获取存储的对应键的存储对象
var objectStoreRequest = objectStore.get(id);
// 获取成功后替换当前数据
objectStoreRequest.onsuccess = function(event) {
// 当前数据
var myRecord = objectStoreRequest.result;
// 遍历替换
for (var key in data) {
if (typeof myRecord[key] != 'undefined') {
myRecord[key] = data[key];
}
}
// 更新数据库存储数据
objectStore.put(myRecord);
};
},
del: function (id) {
// 打开已经存储的数据对象
var objectStore = db.transaction([dbName], "readwrite").objectStore(dbName);
// 直接删除
var objectStoreRequest = objectStore.delete(id);
console.log(objectStoreRequest);
// 删除成功后
objectStoreRequest.onsuccess = function() {
method.show();
};
},
clear: function(){
var objectStore = db.transaction([dbName], 'readwrite').objectStore(dbName);
objectStore.clear();
method.show();lo
},
search: function(val){
var objectStore = db.transaction([dbName], 'readwrite').objectStore(dbName);
var index = objectStore.index('name');
var htmlProjectList = '';
index.openCursor(val).onsuccess = function(){
var cursor = event.target.result;
if (cursor) {
htmlProjectList = htmlProjectList + strTplList.temp(cursor.value);
// 继续下一个游标项
cursor.continue();
// 如果全部遍历完毕
}else {
logInfo('');
eleTbody.innerHTML = htmlProjectList;
if (htmlProjectList == '') {
logInfo('暂无数据');
}
}
};
},
show: function () {
// 最终要展示的HTML数据
var htmlProjectList = '';
// 打开对象存储,获得游标列表
var objectStore = db.transaction(dbName).objectStore(dbName);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
// 如果游标没有遍历完,继续下面的逻辑
if (cursor) {
htmlProjectList = htmlProjectList + strTplList.temp(cursor.value);
// 继续下一个游标项
cursor.continue();
// 如果全部遍历完毕
} else {
logInfo('');
eleTbody.innerHTML = htmlProjectList; if (htmlProjectList == '') {
logInfo('暂无数据');
}
}
}
}
}; // 表单提交新增数据
eleForm.addEventListener('submit', function (event) {
event.preventDefault(); var formData = {}; [].slice.call(this.querySelectorAll('input,textarea')).forEach(function (ele) {
if (ele.name) {
formData[ele.name] = ele.value;
}
}); // 添加新的数据
method.add(formData); this.reset();
}); // 编辑事件
eleTbody.addEventListener('focusout', function (event) {
var eleTd = event.target;
// 获取id,也就是获得主键
var id = eleTd && eleTd.getAttribute('data-id');
if (!id || !/td/.test(eleTd.tagName)) { return; } // 这是要替换的数据
var data = {
id: id * 1
};
// 获得现在的数据
[].slice.call(eleTd.parentElement.querySelectorAll('td[data-key]')).forEach(function (td) {
var key = td.getAttribute('data-key');
var value = td.innerText || td.textContent || ''; data[key] = value;
}); // 更新本地数据库
method.edit(id, data);
});
// 删除事件
eleTbody.addEventListener('click', function (event) {
var eleBtn = event.target, id = '';
if (eleBtn && eleBtn.classList.contains('jsListDel') && (id = eleBtn.getAttribute('data-id'))) {
method.del(id * 1);
event.preventDefault();
}
});
})();
</script>
</body>
</html>
indexedDB入门的更多相关文章
- 浏览器数据库 IndexedDB 入门
一.概述 随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据. 现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的 ...
- 浏览器数据库 IndexedDB 入门教程
一.概述 随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据. 现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的 ...
- IndexedDB参考资料网址
IndexedDB:浏览器里内置的数据库, Web骇客 http://www.webhek.com/indexeddb/ 前端的数据库:IndexedDB入门(很全面) http://web.jobb ...
- 深入了解浏览器存储:对比Cookie、LocalStorage、sessionStorage与IndexedDB
摘要: 对比Cookie.LocalStorage.sessionStorage与IndexedDB 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 随着移动网络的发展与演化,我 ...
- 一文梳理Web存储,从cookie,WebStorage到IndexedDB
前言 HTTP是无状态的协议,网络早期最大的问题之一是如何管理状态.服务器无法知道两个请求是否来自同一个浏览器.cookie应运而生,开始出现在各大网站,然而随着前端应用复杂度的提高,Cookie 也 ...
- Koa 框架教程
Koa 框架教程 作者: 阮一峰 日期: 2017年8月 9日 Node 主要用在开发 Web 应用.这决定了使用 Node,往往离不开 Web 应用框架. Koa 就是一种简单好用的 Web 框 ...
- 有趣的HTML5 Web 存储
HTML5 web 存储,一个比cookie更好的本地存储方式. 什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web ...
- HTML5 indexedDB数据库的入门学习(二)
上一篇关于indexedDB的学习笔记主要写了indexedDB数据库的基本操作—增删改查:但是为什么我们要用indexedDB呢?为什么indexedDB受到了开发者们的青睐呢?最主要的就是inde ...
- HTML5 indexedDB数据库的入门学习(一)
笔者早些时间看过web sql database,但是不再维护和支持,所以最近初步学习了一下indexedDB数据库,首先indexedDB(简称IDB)和web sql database有很大的差别 ...
随机推荐
- 删除排序数组中的重复数字 II
题目连接 http://www.lintcode.com/zh-cn/problem/remove-duplicates-from-sorted-array-ii/ 题目大意 跟进“删除重复数字”: ...
- python进程、多进程
进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...
- Java SE 基础知识(String,Array)
String 类: 1. 对于String对象的相等性判断来说,请使用equals()方法,而不是==.String的equals()是判断当前字符串与传进来的字符串的内容是否一致. 2. Strin ...
- python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法
python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法 同一台机器同时安装 python2.7 和 python3.4不会冲突.安装在不同目录,然 ...
- bootstrap 日期控件常用选项
使用bootstrap作为UI基础之后,为了尽可能的保持系统风格的一致性,通常我们不太会考虑再引入My97DatePicker作为日期控件. 作为潜在实现的选择之一,http://www.bootcs ...
- PHP微信公众号后台开发(Yii2实现)
本文内容较多,包括微信接入.获取微信用户信息.微信支付.JSSDK配置参数获取等部分.如果读者对微信开发没有一个主观上的认识,那么建议读者先研读微信公众平台开发者文档,然后再阅读本文,效果更佳!另外本 ...
- MemcacheQ安装
一.memcacheq介绍 特性: 1.简单易用 2.处理速度快 3.多条队列 4.并发性能好 5.与memcache的协议兼容 6.在zend framework中使用方便 memcacheq依赖于 ...
- centos6.7rsync端与window2012服务器实时文件同步
windows文件共享我就不截图了,估计大家都会,我就直接在centos6.7上操作了一.挂载win共享文件夹mount -t cifs -o username=administrator,passw ...
- Python3基础 str format 四舍六入五凑偶 保留一位小数
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Django组件(四) Django之Auth模块
Auth模块概述 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能 ...