>

HTML5地面存储——IndexedDB

- 编辑:乐百家599手机首页 -

HTML5地面存储——IndexedDB

前端的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁绝转发!
德文出处:www.codemag.com。招待加入翻译组。

应用程序要求多少。对大好些个Web应用程序来讲,数据在服务器端组织和治本,客商端通过互联网央求获取。随着浏览器变得特别有力量,因而可选择在浏览器存款和储蓄和调整应用程序数据。

正文向您介绍名字为IndexedDB的浏览器端文档数据库。使用lndexedDB,你能够经过惯于在劳务器端数据库差相当少等同的秘技开创、读取、更新和删除大量的笔录。请使用本文中可专业的代码版本去心得,完整的源代码能够通过GitHub库找到。

读到本学科的结尾时,你将熟练IndexedDB的基本概念以至怎样达成三个行使IndexedDB实践总体的CRUD操作的模块化JavaScript应用程序。让大家有一点亲昵IndexedDB并最初吧。

什么是IndexedDB

诚如的话,有三种不一样品类的数据库:关系型和文书档案型(也称为NoSQL或对象卡塔尔。关周详据库如SQL Server,MySQL,Oracle的多少存款和储蓄在表中。文档数据库如MongoDB,CouchDB,Redis将数据集作为个体对象存款和储蓄。IndexedDB是二个文书档案数据库,它在一同内放置浏览器中的一个沙盒情况中(强制根据(浏览器)同源战略卡塔尔(قطر‎。图1呈现了IndexedDB的数目,浮现了数据库的构造

乐百家前段 1

图1:开垦者工具查看三个object store

全部的IndexedDB API请参见完整文书档案

深切分析HTML5中的IndexedDB索引数据库,html5indexeddb

那篇随笔紧要介绍了深远剖析HTML5中的IndexedDB索引数据库,富含事务锁等基本效能的连锁应用示例,须求的相爱的人可以参见下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5 WEB应用在客商浏览器端存款和储蓄数据。对于使用来讲IndexedDB特别苍劲、有用,能够在客户端的chrome,IE,Firefox等WEB浏览器中贮存大量数量,上边简介一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的多寡存款和储蓄,能够在客户端存款和储蓄、操作数据,能够使利用加载地越来越快,更加好地响应。它区别于关系型数据库,具有数据表、记录。它影响着大家规划和创办应用程序的情势。IndexedDB 创立有数据类型和简易的JavaScript持久对象的object,各样object能够有目录,使其一蹴而就地查询和遍历整个集合。本文为您提供了哪些在Web应用程序中利用IndexedDB的真人真事事例。
 
开始 我们需求在实践前包括下眼前置代码

JavaScript Code复制内容到剪贴板

  1. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;   
  2.     
  3. //prefixes of window.IDB objects   
  4. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;   
  5. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange   
  6.     
  7. if (!indexedDB) {   
  8. alert("Your browser doesn't support a stable version of IndexedDB.")   
  9. }  

 
打开IndexedDB 在开创数据库以前,我们率先必要为数据库创立数量,若是我们好似下的顾客音信:

JavaScript Code复制内容到剪贴板

  1. var userData = [   
  2. { id: "1", name: "Tapas", age: 33, email: "[email protected]" },   
  3. { id: "2", name: "Bidulata", age: 55, email: "[email protected]" }   
  4. ];  

前日大家需求用open(卡塔尔(英语:State of Qatar)方法展开大家的数据库:

JavaScript Code复制内容到剪贴板

  1. var db;   
  2. var request = indexedDB.open("databaseName", 1);   
  3.     
  4. request.onerror = function(e) {   
  5. console.log("error: ", e);   
  6. };   
  7.     
  8. request.onsuccess = function(e) {   
  9. db = request.result;   
  10. console.log("success: "  db);   
  11. };   
  12. request.onupgradeneeded = function(e) {   
  13.     
  14. }  

如上所示,我们早就开垦了名叫"databaseName",钦点版本号的数据库,open(卡塔尔(قطر‎方法有三个参数:
1.先是个参数是数据库名称,它会检测名为"databaseName"的数据库是不是曾经存在,假如存在则张开它,不然成立新的数据库。
2.次之个参数是数据库的本子,用于顾客更新数据库布局。
 
onSuccess处理 发生成功事件时“onSuccess”被触发,假如具备成功的央浼都在那管理,大家得以由此赋值给db变量保存诉求的结果供未来使用。
 
onerror的管理程序 爆发错误事件时“onerror”被触发,纵然张开数据库的长河中告负。
 
Onupgradeneeded管理程序 倘使您想翻新数据库(创造,删除或改革数据库),那么你必须要兑现onupgradeneeded管理程序,使您能够在数据库中做任何改动。 在“onupgradeneeded”管理程序中是足以改革数据库的布局的独步天下地点。
 
成立和增进数据到表:
IndexedDB使用对象存款和储蓄来累积数据,而不是透过表。 每当叁个值存款和储蓄在指标存款和储蓄中,它与三个键相关联。 它同意大家成立的别的对象存款和储蓄索引。 索引允许我们拜访存款和储蓄在对象存款和储蓄中的值。 下边包车型大巴代码呈现了何等创造对象存款和储蓄并插入预先筹划好的数额:

JavaScript Code复制内容到剪贴板

  1. request.onupgradeneeded = function(event) {   
  2. var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});   
  3. for (var i in userData) {   
  4. objectStore.add(userData[i]);    
  5. }   
  6. }  

作者们使用createObjectStore()方法创制三个对象存款和储蓄。 此方法选取八个参数:

  • 累积的名目和参数对象。 在这里间,大家有二个名称为"users"的靶子存款和储蓄,并定义了keyPath,那是目的唯风姿浪漫性的性质。 在那,大家运用“id”作为keyPath,那么些值在目的存储中是独步天下的,大家必须要有限支撑该“ID”的特性在目的存储中的每一个对象中留存。 大器晚成旦成立了对象存款和储蓄,大家能够开端选择for循环增添数据进去。
     
    手动将数据增进到表:
    咱俩得以手动增多额外的数额到数据库中。

JavaScript Code复制内容到剪贴板

  1. function Add() {   
  2. var request = db.transaction(["users"], "readwrite").objectStore("users")   
  3. .add({ id: "3", name: "Gautam", age: 30, email: "[email protected]" });   
  4.     
  5. request.onsuccess = function(e) {   
  6. 乐百家前段,alert("Gautam has been added to the database.");   
  7. };   
  8.     
  9. request.onerror = function(e) {   
  10. alert("Unable to add the information.");    
  11. }   
  12.     
  13. }  

后边大家在数据库中做其余的CRUD操作(读,写,改正),必得利用职业。 该transaction(卡塔尔国方法是用来钦定我们想要实行事务管理的对象存款和储蓄。 transaction(卡塔尔(قطر‎方法采用3个参数(第二个和第八个是可选的)。 第二个是大家要处理的靶子存储的列表,第三个钦赐大家是还是不是要只读/读写,第4个是本子变化。
 
从表中读取数据 get(卡塔尔(英语:State of Qatar)方法用于从指标存款和储蓄中寻觅数据。 大家前边已经设置对象的id作为的keyPath,所以get(卡塔尔(英语:State of Qatar)方法将追寻具备同等id值的靶子。 上面包车型大巴代码将赶回大家命名称为“Bidulata”的对象:

JavaScript Code复制内容到剪贴板

  1. function Read() {   
  2. var objectStore = db.transaction(["users"]).objectStore("users");   
  3. var request = objectStore.get("2");   
  4. request.onerror = function(event) {   
  5. alert("Unable to retrieve data from database!");   
  6. };   
  7. request.onsuccess = function(event) {    
  8. if(request.result) {   
  9. alert("Name: "   request.result.name   ", Age: "   request.result.age   ", Email: "   request.result.email);   
  10. } else {   
  11. alert("Bidulata couldn't be found in your database!");    
  12. }   
  13. };   
  14. }  

 
从表中读取全体数据
上边包车型大巴措施寻觅表中的全体数据。 这里我们接纳游标来查找对象存款和储蓄中的全数数据:

JavaScript Code复制内容到剪贴板

  1. function ReadAll() {   
  2. var objectStore = db.transaction("users").objectStore("users");    
  3. var req = objectStore.openCursor();   
  4. req.onsuccess = function(event) {   
  5. db.close();   
  6. var res = event.target.result;   
  7. if (res) {   
  8. alert("Key "   res.key   " is "   res.value.name   ", Age: "   res.value.age   ", Email: "   res.value.email);   
  9. res.continue();   
  10. }   
  11. };   
  12. req.onerror = function (e) {   
  13. console.log("Error Getting: ", e);   
  14. };    
  15. }  

该openCursor(卡塔尔国用于遍历数据库中的几个记录。 在continue(卡塔尔国函数中继续读取下一条记下。
去除表中的笔录 上边包车型地铁格局从指标中删除记录。

JavaScript Code复制内容到剪贴板

  1. function Remove() {    
  2. var request = db.transaction(["users"], "readwrite").objectStore("users").delete("1");   
  3. request.onsuccess = function(event) {   
  4. alert("Tapas's entry has been removed from your database.");   
  5. };   
  6. }  

大家要将指标的keyPath作为参数字传送递给delete(卡塔尔国方法。
 
最终代码
下边包车型地铁艺术从目的源中删除一条记下:

JavaScript Code复制内容到剪贴板

  1. <!DOCTYPE html>  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  4. <title>IndexedDB</title>  
  5. <script type="text/javascript">  
  6. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;   
  7.     
  8. //prefixes of window.IDB objects   
  9. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;   
  10. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange   
  11.     
  12. if (!indexedDB) {   
  13. alert("Your browser doesn't support a stable version of IndexedDB.")   
  14. }   
  15. var customerData = [   
  16. { id: "1", name: "Tapas", age: 33, email: "[email protected]" },   
  17. { id: "2", name: "Bidulata", age: 55, email: "[email protected]" }   
  18. ];   
  19. var db;   
  20. var request = indexedDB.open("newDatabase", 1);   
  21.     
  22. request.onerror = function(e) {   
  23. console.log("error: ", e);   
  24. };   
  25.     
  26. request.onsuccess = function(e) {   
  27. db = request.result;   
  28. console.log("success: "  db);   
  29. };   
  30.     
  31. request.onupgradeneeded = function(event) {   
  32.     
  33. }   
  34. request.onupgradeneeded = function(event) {   
  35. var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});   
  36. for (var i in userData) {   
  37. objectStore.add(userData[i]);    
  38. }   
  39. }   
  40. function Add() {   
  41. var request = db.transaction(["users"], "readwrite")   
  42. .objectStore("users")   
  43. .add({ id: "3", name: "Gautam", age: 30, email: "[email protected]" });   
  44.     
  45. request.onsuccess = function(e) {   
  46. alert("Gautam has been added to the database.");   
  47. };   
  48.     
  49. request.onerror = function(e) {   
  50. alert("Unable to add the information.");    
  51. }   
  52.     
  53. }   
  54. function Read() {   
  55. var objectStore = db.transaction("users").objectStore("users");   
  56. var request = objectStore.get("2");   
  57. request.onerror = function(event) {   
  58. alert("Unable to retrieve data from database!");   
  59. };   
  60. request.onsuccess = function(event) {    
  61. if(request.result) {   
  62. alert("Name: "   request.result.name   ", Age: "   request.result.age   ", Email: "   request.result.email);   
  63. } else {   
  64. alert("Bidulata couldn't be found in your database!");    
  65. }   
  66. };   
  67. }   
  68. function ReadAll() {   
  69. var objectStore = db.transaction("users").objectStore("users");    
  70. var req = objectStore.openCursor();   
  71. req.onsuccess = function(event) {   
  72. db.close();   
  73. var res = event.target.result;   
  74. if (res) {   
  75. alert("Key "   res.key   " is "   res.value.name   ", Age: "   res.value.age   ", Email: "   res.value.email);   
  76. res.continue();   
  77. }   
  78. };   
  79. req.onerror = function (e) {   
  80. console.log("Error Getting: ", e);   
  81. };    
  82. }   
  83. function Remove() {    
  84. var request = db.transaction(["users"], "readwrite").objectStore("users").delete("1");   
  85. request.onsuccess = function(event) {   
  86. alert("Tapas's entry has been removed from your database.");   
  87. };   
  88. }   
  89. </script>  
  90. </head>  
  91.     
  92. <body>  
  93. <button onclick="Add()">Add record</button>  
  94. <button onclick="Remove()">Delete record</button>  
  95. <button onclick="Read()">Retrieve single record</button>  
  96. <button onclick="ReadAll()">Retrieve all records</button>  
  97. </body>  
  98. </html>  

localStorage是不带lock功用的。那么要落到实处前端的多寡分享何况供给lock成效那就须求动用其它本积存方式,比方indexedDB。indededDB使用的是事务管理的机制,那其实正是lock功能。
  做这些测验必要先轻松的卷入下indexedDB的操作,因为indexedDB的接连相比较麻烦,何况四个测验页面都亟待用到

JavaScript Code复制内容到剪贴板

  1. //db.js   
  2. //封装事务操作   
  3. IDBDatabase.prototype.doTransaction=function(f){   
  4.   f(this.transaction(["Obj"],"readwrite").objectStore("Obj"));   
  5. };   
  6. //连接数据库,成功后调用main函数   
  7. (function(){   
  8.   //张开数据库   
  9.   var cn=indexedDB.open("TestDB",1);   
  10.   //创造数量对象   
  11.   cn.onupgradeneeded=function(e){   
  12.     e.target.result.createObjectStore("Obj");   
  13.   };   
  14.   //数据库连接成功   
  15.   cn.onsuccess=function(e){   
  16.     main(e.target.result);   
  17.   };   
  18. })();   
  19.   接着是多少个测量检验页面   
  20. <script src="db.js"></script>  
  21. <script>  
  22. //a.html   
  23. function main(e){   
  24.   (function callee(){   
  25.     //开端三个业务   
  26.     e.doTransaction(function(e){   
  27.       e.put(1,"test"); //设置test的值为1   
  28.       e.put(2,"test"); //设置test的值为2   
  29.     });   
  30.     setTimeout(callee);   
  31.   })();   
  32. };   
  33. </script>  
  34. <script src="db.js"></script>  
  35. <script>  
  36. //b.html   
  37. function main(e){   
  38.   (function callee(){   
  39.     //开头叁个事情   
  40.     e.doTransaction(function(e){   
  41.       //获取test的值   
  42.       e.get("test").onsuccess=function(e){   
  43.         console.log(e.target.result);   
  44.       };   
  45.     });   
  46.     setTimeout(callee);   
  47.   })();   
  48. };   
  49. </script>  

把localStorage换来了indexedDB事务管理。然而结果就差别

乐百家前段 2

测量试验的时候b.html中或许不会即时有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了政工丢队列中等待。可是无论怎样,输出结果也不会是1那个值。因为indexedDB的眇小处理单位是事情,并不是localStorage那样以表达式为单位。那样假若把lock和unlock之间供给管理的东西放入三个业务中就可以实现。此外,浏览器对indexedDB的支撑不及localStorage,所以利用时还得思谋浏览器包容。

那篇文章首要介绍了入木四分剖析HTML5中的IndexedDB索引数据库,包含事务锁等基本作用的连带使...

简介

在做web开采的时候,一时候须求仓库储存一些缓存数据,幸免后一次拜谒的时候再一次加载多量数码,假设只是存在session、cookies里面,会很影响进程,而且session和cookies存款和储蓄的数码都比较轻便,无法积攒一些结构化的数额,html5提供了风度翩翩项相比实用的本地存款和储蓄本领IndexedDB,就如安装在浏览器上的数据库同样,可是使用办法跟经常的数据库有个别不相似,完全使用js的方式来促成创设删除数据库以至数据的增加和删除改查。
<pre>
var version=version || 1,db;
//连接数据库(展开句柄卡塔尔
var request=window.indexedDB.open('mydb',version);
request.onerror=function(e){ console.log(e.currentTarget.error.message); };
//连接成功后
request.onsuccess=function(e){
db=e.target.result;
//创设'数据表'students(应该叫object store,indexedDB中绝非表的定义,而是objectStore,一个数据库中得以蕴涵三个objectStore
//objectStore是二个心闲手敏的数据构造,能够存放六种类型数据。也正是说一个objectStore也便是一张表,里面积累的每条数据和三个键相关联。

安插指南

IndexedDB的构造很像在某些风行的服务器端NOSQL数据库完结中的设计指南类型。面向对象数据经过object stores(对象旅馆)进行悠久化,全部操作基于诉求相同的时间在专门的学问节制内进行。事件生命周期使您可以见到调整数据库的布署,错误通过荒诞冒泡来使用API管理。

IndexedDB是HTML5中的新添效果与利益。互连网数据库托管并留存在用户的浏览器内。只要让开荒人士通过增添的查询成效创设应用,就足以预言到,将会现身能够同期在线和离线使用的新型网络利用。

//大家能够使用每条记下中的有个别钦定字段作为键值(keyPath),也得以利用自动生成的依次增加数字作为键值(keyGenerator)
//也足以不点名。接收键的品类不一致,objectStore能够储存的数据构造也可能有间距
if(!db.objectStoreNames.contains('students')){
db.createObjectStore('students',{keyPath:"id"});
}
var students=[{
id:1001,
name:"Byron",
age:24
},{
id:1002,
name:"Frank",
age:30
},{
id:1003,
name:"Aaron",
age:26
}];
var transaction=db.transaction('students','readwrite');
var store=transaction.objectStore('students');
//找到呼应‘表’ 插入数据
for(var i=0;i<students.length;i ){
store.add(students[i]);
}
};
//查询数据
function getDataByKey(db,dbName,value){
var transaction=db.transaction(dbName,'readwrite');
var store=transaction.objectStore(dbName);
var request=store.get(value);
request.onsuccess=function(e){ var student=e.target.result; console.log(student.name); };
}
//更新数据
function updateDataByKey(db,dbName,value){
var transaction=db.transaction(dbName,'readwrite');
var store=transaction.objectStore(dbName);
var request=store.get(value);
request.onsuccess=function(e){
var student=e.target.result;
student.age=35;
store.put(student);
};
}
</pre>

目的货仓

object store是IndexedDB数据库的底子。假诺你利用过关周详据库,平时能够将object store等价于三个数据库表。Object stores包涵多少个或多少个目录,在store中依照大器晚成对键/值操作,这提供后生可畏种高效稳固数据的主意。

当你安顿叁个object store,你必得为store选用贰个键。键在store中能够以“in-line”或“out-of-line”的主意存在。in-line键通过在数量对象上援引path来保险它在object store的唯风姿罗曼蒂克性。为了验证这点,想想一个包罗电子邮件地址属性Person对象。您能够布署你的store使用in-line键emailAddress,它能确认保障store(持久化对象中的数据)的独一性。别的,out-of-line键通过独立于数据的值识别唯意气风发性。在此种情形下,你能够把out-of-line键比作叁个莫西干发型值,它(整数值)在关周全据库中充作记录的主键。

图1出示了任务数据保存在职分的object store,它使用in-line键。在此个案例中,键对应于对象的ID值。

 

依照事务

差别于一些金钱观的关周密据库的兑现,每叁个对数据库操作是在多个职业的前后文中试行的。事务节制一回影响三个或多个object stores,你通过传播三个object store名字的数组到创立职业限定的函数来定义。

开创专门的学业的第3个参数是工作情势。当倡议贰个事务时,必得决定是坚决守住只读还是读写情势央浼访谈。事务是财富密集型的,所以大器晚成旦你没有必要校正data store中的数据,你只必要以只读方式对object stores会集实行倡议访谈。

清单2示范了怎么样运用特别的情势创建一个作业,并在这里片小说的 Implementing Database-Specific Code 部分进行了详尽座谈。

IndexedDB是什么?

基于央求

截止这里,有一个反复现身的宗旨,您也许曾经注意到。对数据库的历次操作,描述为通过三个伸手展开数据库,访谈三个object store,再持续。IndexedDB API天生是依据乞求的,那也是API异步性情提醒。对于你在数据库实行的历次操作,你必须要首先为那几个操作创造八个诉求。当号召完结,你能够响应由要求结果爆发的平地风波和谬误。

正文完毕的代码,演示了怎么运用央浼展开数据库,创立多个业务,读取object store的内容,写入object store,清空object store。

IndexedDB是指标存款和储蓄,它差别于带有表格(包括行和列的聚合)的关全面据库。那是一位命关天的根本分裂,並且会影响你设计和创设利用的主意。

开拓数据库的伸手生命周期

IndexedDB使用事件生命周期管理数据库的展开和布置操作。图2示范了多少个开采的伸手在必然的条件下产生upgrade need事件。

乐百家前段 3

图2:IndexedDB张开要求的生命周期

抱有与数据库的相互带头于三个开采的乞求。试图张开数据库时,您必得传递二个被呼吁数据库的版本号的整数值。在开垦必要时,浏览器相比较你传入的用于打开央浼的版本号与实际数据库的版本号。倘使所央浼的版本号高于浏览器中当前的版本号(也许今后没有存在的数据库卡塔尔(英语:State of Qatar),upgrade needed事件触发。在uprade need事件之间,你有空子通过丰富或移除stores,键和索引来操纵object stores。

假使所央浼的数据库版本号和浏览器的近年来版本号相同,可能晋级历程一鼓作气,四个开垦的数据库将回到给调用者。

 

荒唐冒泡

当然,一时候,须求恐怕不会按预期实现。IndexedDB API通过荒谬冒泡效果来扶植追踪和治本漏洞非常多。假设一个一定的乞请遇到错误,你可以品尝在伸手对象上管理错误,或许您能够允许错误通过调用栈冒泡向上传递。那几个冒泡天性,使得你不须求为各个需要完结特定错误管理操作,而是能够筛选只在二个越来越高档别上增添错误管理,它给您一个机会,保持你的错误管理代码简洁。本文中落实的事例,是在一个高档别管理错误,以便越来越细粒度操作爆发的此外错误冒泡到通用的错误管理逻辑。

在思想的关周密据存款和储蓄中,大家有叁个“待办事项”的报表,此中各行存款和储蓄了客户待办事项数据的聚合,而各列则是数码的命名类型。要插入数据,常常采纳如下语义:INSERTINTO Todo(id, data, update_time) VALUES (1, "Test","01/01/2010");

浏览器帮助

大概在开垦Web应用程序最要害的主题素材是:“浏览器是不是扶助本人想要做的?“纵然浏览器对IndexedDB的帮助在持续巩固,选用率并非我们所愿意的这样分布。图3显得了caniuse.com网址的告知,协助IndexedDB的为66%多一丢丢。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全补助IndexedDB,Internet Explorer和One plus部分帮忙。尽管那个列表的拥护者是动人心弦的,但它并未有报告全部旧事。

乐百家前段 4

图3:浏览器对IndexedDB的援救,来自caniuse.com

唯有丰盛新本子的Safari和iOS Safari 援助IndexedDB。据caniuse.com彰显,那只占差不离0.01%的天下浏览器接收。IndexedDB不是三个你以为能够道理当然是那样的获得辅助的现世Web API,可是你将异常快会那样认为。

 

另生龙活虎种采取

浏览器扶持当地数据库并非从IndexedDB才起来兑现,它是在WebSQL贯彻之后的大器晚成种新办法。相同IndexedDB,WebSQL是叁个客商端数据库,但它充任四个关周密据库的达成,使用构造化查询语言(SQL卡塔尔国与数据库通讯。WebSQL的野史充满了波折,但底线是平素不主流的浏览器商家对WebSQL继续辅助。

假定WebSQL实际上是叁个甩掉的手艺,为啥还要提它吗?风趣的是,WebSQL在浏览器里拿走稳步的支撑。Chrome, Safari, iOS Safari, and Android 浏览器都补助。此外,并非这一个浏览器的新颖版本才提供支持,多数那一个新式最佳的浏览器早先的本子也足以支撑。风趣的是,假让你为WebSQL加多帮助来协理IndexedDB,你蓦然意识,好些个浏览器商家和版本成为帮助浏览器内置数据库的某种化身。

为此,假设你的应用程序真正须求叁个客商端数据库,你想要达到的最高端其他应用可能,当IndexedDB不可用时,只怕你的应用程序大概看起来须要接收选择WebSQL来扶助顾客端数据布局。即便文书档案数据库和关周到据库管理数据有醒目标差异,但万生龙活虎您有精确的空洞,就能够动用本地数据库构建贰个应用程序。

IndexedDB的分裂之处在于,您能够成立有些项目数据的目的存款和储蓄,然后只需将JavaScript对象留存在该存款和储蓄中就可以。各类对象存款和储蓄都足以有目录的汇集,那样就能够开展火速的查询和迭代。

IndexedDB是不是切合小编的应用程序?

近日最入眼的问题:“IndexedDB是或不是符合本人的应用程序?“像在此以前生机勃勃致,答案是一定的:“视意况而定。“首先当您希图在顾客端保存数据时,你会设想HTML5本土存款和储蓄。本地存款和储蓄获得分布浏览器的支撑,有极度便于使用的API。轻便有其优势,但其劣点是爱莫能助支撑复杂的搜索计策,存款和储蓄多量的数目,并提供工作援救。

IndexedDB是贰个数据库。所以,当你想为顾客端做出决定,考虑你如何在服务端选拔五个长久化介质媒质的数据库。你可能会问本身有个别标题来扶助调节客商端数据库是还是不是相符你的应用程序,包蕴:

  • 您的客户通过浏览器访问您的应用程序,(浏览器)援助IndexedDB API吗 ?
  • 您需求仓库储存多量的多寡在顾客端?
  • 你须要在一个巨型的数码会集中高速稳固单个数分公司?
  • 你的构造在客户端须求专业匡助呢?

设若你对此中的其他难题回复了“是的”,很有比超级大可能率,IndexedDB是你的应用程序的七个很好的候选。

 

使用IndexedDB

最近,你曾经有时机熟习了有的的欧洲经济共同体概念,下一步是开始兑现基于IndexedDB的应用程序。第一个步骤须要统后生可畏IndexedDB在差异浏览器的完结。您可以比较轻易地丰硕各个商家特性的选项的反省,同偶尔间在window对象上把它们设置为官方对象相像的称谓。上面包车型大巴清单彰显了window.indexedDB,window.IDBTransaction,window.IDBKeyRange的末尾结果是怎么都被更新,它们棉被服装置为对应的浏览器的特定实现。

JavaScript

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

1
2
3
4
5
6
7
8
9
10
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;

现行反革命,各类数据库相关的大局对象具有正确的版本,应用程序能够准备接收IndexedDB开头工作。

IndexedDB 还裁撤了标准查询语言( SQL卡塔尔(قطر‎的概念,取代他的是针对性索引的查询,那样能够生出二个指南针,用于在结果集以内迭代。

利用概述

在本教程中,您将学习怎么着成立贰个行使IndexedDB存款和储蓄数据的模块化JavaScript应用程序。为了领会应用程序是哪些做事的,参谋图4,它汇报了职务应用程序处于空白状态。从今以往处您可认为列表增加新职分。图5来得了录入了几个职责到系统的画面。图6出示怎么删除二个职务,图7显示了正在编写制定任务时的应用程序。

乐百家前段 5

图4:空白的任务应用程序

乐百家前段 6

图5:职责列表

乐百家前段 7

图6:删除职责

乐百家前段 8

图7:编辑职务
今昔你理解的应用程序的效果与利益,下一步是开始为网站铺设底蕴。

 

铺设底蕴

本条例子从落实那样一个模块最早,它承当从数据库读取数据,插入新的靶子,更新现成对象,删除单个对象和提供在二个object store删除全体指标的选项。这些例子实现的代码是通用的多少访谈代码,您能够在任何object store上行使。

其一模块是经过四个立即施行函数表达式(IIFE卡塔尔完成,它利用对象字面量来提供协会。下边包车型客车代码是模块的摘要,表明了它的主导构造。

JavaScript

(function (window) { 'use strict'; var db = { /* implementation here */ }; window.app = window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
(function (window) {
    'use strict';
    var db = {
        /* implementation here */
    };
    window.app = window.app || {};
    window.app.db = db;
}(window));

用如此的构造,能够使那么些应用程序的有着逻辑封装在一个名字为app的单对象上。其他,数据库相关的代码在三个名叫db的app子对象上。

以此模块的代码应用IIFE,通过传递window对象来作保模块的适用范围。使用use strict确定保证那一个函数的代码函数是比照(javascript严厉情势)严谨编写翻译法则。db对象作为与数据库交互作用的装有函数的基本点容器。最终,window对象检查app的实例是还是不是留存,倘诺存在,模块使用当前实例,假设不设有,则创建一个新指标。大器晚成旦app对象成功重返或创办,db对象附加到app对象。

正文的别的部分将代码增添到db对象内(在implementation here会讲评卡塔尔(قطر‎,为应用程序提供特定于数据库的逻辑。由此,如您所见本文前边的某些中定义的函数,出主意父db对象活动,但全部任何职能都以db对象的成员。完整的数据库模块列表见项目清单2。

本学科只是举了一个实际上示例,告诉您针对编写为使用WebSQL 的水保应用如何使用IndexedDB。 

Implementing Database-Specific Code

对数据库的每种操作关联着一个先决条件,即有三个开荒的数据库。当数据库正在被打开时,通过检查数据库版本来判别数据库是还是不是必要别的变动。上边的代码突显了模块怎么样跟踪当前版本,object store名、某成员(保存了假如数据库张开必要实现后的数据库当前实例)。

JavaScript

version: 1, objectStoreName: 'tasks', instance: {},

1
2
3
version: 1,
objectStoreName: 'tasks',
instance: {},

在这里地,数据库张开诉求发生时,模块需要版本1数据库。借使数据库不真实,可能版本小于1,upgrade needed事件在张开央求实现前触发。那些模块被安装为只使用八个object store,所以名字直接定义在这里边。最终,实例成员被创造,它用于保存后生可畏旦张开央求达成后的数据库当前实例。

接下去的操作是促成upgrade needed事件的事件管理程序。在此,检查当前object store的名字来剖断央求的object store名是不是留存,要是一纸空文,成立object store。

JavaScript

upgrade: function (e) { var _db = e.target.result, names = _db.objectStoreNames, name = db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore( name, { keyPath: 'id', autoIncrement: true }); } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upgrade: function (e) {
    var
        _db = e.target.result,
        names = _db.objectStoreNames,
        name = db.objectStoreName;
    if (!names.contains(name)) {
        _db.createObjectStore(
            name,
            {
                keyPath: 'id',
                autoIncrement: true
            });
    }
},

在此个事件管理程序里,通过事件参数e.target.result来访问数据库。当前的object store名称的列表在_db.objectStoreName的字符串数组上。今后,要是object store不设有,它是因此传递object store名称和store的键的定义(自增,关联到数码的ID成员)来创设。

模块的下叁个效用是用来捕获错误,错误在模块差异的倡议创设时冒泡。

JavaScript

errorHandler: function (error) { window.alert('error: ' error.target.code); debugger; },

1
2
3
4
errorHandler: function (error) {
    window.alert('error: ' error.target.code);
    debugger;
},

在这里间,errorHandler在二个警示框突显其它错误。那么些函数是画蛇著足保持轻易,对开垦本人,当您学习使用IndexedDB,您能够比较轻巧地看见其余不当(当她们爆发时)。当你计划在生养意况使用那个模块,您必要在此个函数中落到实处部分错误处理代码来和你的应用程序的上下文打交道。

目前根底实现了,那后生可畏节的别的部分将演示怎样贯彻对数据库实行一定操作。第贰个必要检讨的函数是open函数。

JavaScript

open: function (callback) { var request = window.indexedDB.open( db.objectStoreName, db.version); request.onerror = db.errorHandler; request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) { db.instance = request.result; db.instance.onerror = db.errorHandler; callback(); }; },

1
2
3
4
5
6
7
8
9
10
11
12
open: function (callback) {
    var request = window.indexedDB.open(
        db.objectStoreName, db.version);
    request.onerror = db.errorHandler;
    request.onupgradeneeded = db.upgrade;
    request.onsuccess = function (e) {
        db.instance = request.result;
        db.instance.onerror =
            db.errorHandler;
        callback();
    };
},

open函数试图张开数据库,然后施行回调函数,告知数据库成功开采方可策动利用。通过拜见window.indexedDB调用open函数来创立张开央求。这几个函数接纳你想展开的object store的称号和您想采用的数据库版本号。

要是央浼的实例可用,第一步要开展的劳作是安装错误管理程序和进级换代函数。记住,当数据库被张开时,假诺脚本乞求比浏览器里越来越高版本的数据库(恐怕只要数据库不设有卡塔尔国,晋级函数运营。但是,借使须求的数据库版本相称当前数据库版本相同的时间未有不当,success事件触发。

假使整个成功,展开数据库的实例能够从号召实例的result属性获得,这些实例也缓存到模块的实例属性。然后,onerror事件设置到模块的errorHandler,作为现在其它须求的错误捕捉管理程序。末了,回调被实行来告诉调用者,数据库已经张开并且准确地配置,能够使用了。

下二个要兑现的函数是helper函数,它回到所乞求的object store。

JavaScript

getObjectStore: function (mode) { var txn, store; mode = mode || 'readonly'; txn = db.instance.transaction( [db.objectStoreName], mode); store = txn.objectStore( db.objectStoreName); return store; },

1
2
3
4
5
6
7
8
9
getObjectStore: function (mode) {
    var txn, store;
    mode = mode || 'readonly';
    txn = db.instance.transaction(
        [db.objectStoreName], mode);
    store = txn.objectStore(
        db.objectStoreName);
    return store;
},

在那,getObjectStore选拔mode参数,允许你决定store是以只读照旧读写情势需要。对于这几个函数,暗中同意mode是只读的。

各样针对object store的操作都以在叁个事物的前后文中实施的。事务央浼接纳七个object store名字的数组。这些函数此次被布置为只行使多少个object store,不过倘使您须求在专业中操作八个object store,你必要传递五个object store的名字到数组中。事务函数的第二个参数是三个方式。

只要事情央浼可用,您就足以通过传递须求的object store名字来调用objectStore函数以得到object store实例的访问权。那几个模块的别样函数使用getObjectStore来获取object store的访谈权。

下三个兑现的函数是save函数,实践插入或更新操作,它根据传入的数码是不是有二个ID值。

JavaScript

save: function (data, callback) { db.open(function () { var store, request, mode = 'readwrite'; store = db.getObjectStore(mode), request = data.id ? store.put(data) : store.add(data); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
12
save: function (data, callback) {
    db.open(function () {
        var store, request,
            mode = 'readwrite';
 
        store = db.getObjectStore(mode),
        request = data.id ?
            store.put(data) :
            store.add(data);
        request.onsuccess = callback;
    });
},

save函数的三个参数分别是须求保留的数额对象实例和操作成功后供给奉行的回调。读写方式用于将数据写入数据库,它被传出到getObjectStore来收获object store的八个可写实例。然后,检查数据对象的ID成员是还是不是留存。假如存在ID值,数据必得创新,put函数被调用,它创造长久化央浼。不然,倘使ID不设有,那是新数据,add央浼重返。最终,不管put只怕add 必要是还是不是施行了,success事件管理程序须要安装在回调函数上,来告诉调用脚本,一切进展顺遂。

下意气风发节的代码在清单1所示。getAll函数首先张开数据库和做客object store,它为store和cursor(游标)分别设置值。为数据库游标设置游标变量允许迭代object store中的数据。data变量设置为四个空数组,充作数据的器皿,它回到给调用代码。

在store访谈数据时,游标遍历数据库中的每条记下,会触发onsuccess事件管理程序。当每条记下拜见时,store的数据能够透过e.target.result事件参数获得。就算事实上多少从target.result的value属性中得到,首先须求在思忖访问value属性前确定保证result是二个管用的值。假若result存在,您能够增添result的值到数据数组,然后在result对象上调用continue函数来一连迭代object store。最后,若无reuslt了,对store数据的迭代结束,同期数据传递到回调,回调被实施。

前几天模块能够从data store拿到所有数据,下叁个索要贯彻的函数是肩负访问单个记录。

JavaScript

get: function (id, callback) { id = parseInt(id); db.open(function () { var store = db.getObjectStore(), request = store.get(id); request.onsuccess = function (e){ callback(e.target.result); }; }); },

1
2
3
4
5
6
7
8
9
10
11
get: function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            store = db.getObjectStore(),
            request = store.get(id);
        request.onsuccess = function (e){
            callback(e.target.result);
        };
    });
},

get函数推行的首先步操作是将id参数的值转变为三个整数。决议于函数被调用时,字符串或整数都或许传递给函数。那一个达成跳过了对要是所给的字符串不能够调换到整数该如何做的情事的管理。黄金时代旦一个id值筹划好了,数据库张开了和object store可以访谈了。获取访谈get伏乞出现了。诉求成功时,通过传播e.target.result来实践回调。它(e.target.result)是透过调用get函数到手的单条记录。

将来保存和筛选操作已经冒出了,该模块还索要从object store移除数量。

JavaScript

'delete': function (id, callback) { id = parseInt(id); db.open(function () { var mode = 'readwrite', store, request; store = db.getObjectStore(mode); request = store.delete(id); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
'delete': function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            mode = 'readwrite',
            store, request;
        store = db.getObjectStore(mode);
        request = store.delete(id);
        request.onsuccess = callback;
    });
},

delete函数的称号用单引号,因为delete是JavaScript的保留字。那足以由你来决定。您能够接收命名函数为del或任何名目,但是delete用在这里个模块为了API尽大概好的发挥。

传送给delete函数的参数是指标的id和三个回调函数。为了保全这几个达成轻松,delete函数约定id的值为整数。您能够选用创设叁个更完善的兑现来管理id值无法深入分析成整数的不当例子的回调,但为了指点原因,代码示例是心存不轨的。

假设id值能确定保障转换成一个整数,数据库被张开,三个可写的object store拿到,delete函数字传送入id值被调用。当倡议成功时,将实践回调函数。

在好几情形下,您或然必要删除多少个object store的兼具的笔录。在此种状态下,您访问store同不常间湮灭全体内容。

JavaScript

deleteAll: function (callback) { db.open(function () { var mode, store, request; mode = 'readwrite'; store = db.getObjectStore(mode); request = store.clear(); request.onsuccess = callback; }); }

1
2
3
4
5
6
7
8
9
deleteAll: function (callback) {
    db.open(function () {
        var mode, store, request;
        mode = 'readwrite';
        store = db.getObjectStore(mode);
        request = store.clear();
        request.onsuccess = callback;
    });
}

那边deleteAll函数担当张开数据库和做客object store的贰个可写实例。生机勃勃旦store可用,二个新的号召通过调用clear函数来创设。生机勃勃旦clear操作成功,回调函数被推行。

 

试行客商分界面特定代码

当今具备特定于数据库的代码被封装在app.db模块中,客商分界面特定代码能够运用此模块来与数据库交互作用。客户分界面特定代码的欧洲经济共同体清单(index.ui.js卡塔尔国能够在项目清单3中拿走,完整的(index.html卡塔尔(قطر‎页面包车型地铁HTML源代码能够在清单4中获得。

怎么是 IndexedDB?

结论

随着应用程序的急需的压实,你会发今后客商端高效存款和储蓄大批量的数码的优势。IndexedDB是足以在浏览器中一贯动用且支持异步事务的文档数据库达成。即便浏览器的支撑大概还是不能够保全,但在切合的状态下,集成IndexedDB的Web应用程序具备强盛的客商端数据的访谈本事。

在大部情形下,全部针对IndexedDB编写的代码是自然基于恳求和异步的。官方正规有同步API,可是这种IndexedDB只相符web worker的光景文中使用。这篇文章发表时,还尚无浏览器达成的一块儿格式的IndexedDB API。

必然要保管代码在此外函数域外对商家特定的indexedDB, IDBTransaction, and IDBKeyRange实例进行了规范化且使用了凶横方式。那允许你防止浏览器错误,当在strict mode下剖析脚本时,它不会容许你对那个对象重新赋值。

你必得保证只传递正整数的本子号给数据库。传递到版本号的小数值会四舍五入。因而,如若你的数据库近些日子版本1,您寻思访谈1.2本子,upgrade-needed事件不会接触,因为版本号最后评估是同样的。

马上实践函数表明式(IIFE卡塔尔(英语:State of Qatar)一时叫做不一样的名字。不常能够见到这么的代码协会措施,它称为self-executing anonymous functions(自实行佚名函数)或self-invoked anonymous functions(自调用无名函数)。为越发解释那么些名称相关的谋算和含义,请阅读Ben Alman的篇章Immediately Invoked Function Expression (IIFE) 。

Listing 1: Implementing the getAll function

JavaScript

getAll: function (callback) { db.open(function () { var store = db.getObjectStore(), cursor = store.openCursor(), data = []; cursor.onsuccess = function (e) { var result = e.target.result; if (result && result !== null) { data.push(result.value); result.continue(); } else { callback(data); } }; }); },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
getAll: function (callback) {
 
    db.open(function () {
 
        var
            store = db.getObjectStore(),
            cursor = store.openCursor(),
            data = [];
 
        cursor.onsuccess = function (e) {
 
            var result = e.target.result;
 
            if (result &&
                result !== null) {
 
                data.push(result.value);
                result.continue();
 
            } else {
 
                callback(data);
            }
        };
 
    });
},

Listing 2: Full source for database-specific code (index.db.js)

JavaScript

// index.db.js ; window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; (function(window){ 'use strict'; var db = { version: 1, // important: only use whole numbers! objectStoreName: 'tasks', instance: {}, upgrade: function (e) { var _db = e.target.result, names = _db.objectStoreNames, name = db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore( name, { keyPath: 'id', autoIncrement: true }); } }, errorHandler: function (error) { window.alert('error: ' error.target.code); debugger; }, open: function (callback) { var request = window.indexedDB.open( db.objectStoreName, db.version); request.onerror = db.errorHandler; request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) { db.instance = request.result; db.instance.onerror = db.errorHandler; callback(); }; }, getObjectStore: function (mode) { var txn, store; mode = mode || 'readonly'; txn = db.instance.transaction( [db.objectStoreName], mode); store = txn.objectStore( db.objectStoreName); return store; }, save: function (data, callback) { db.open(function () { var store, request, mode = 'readwrite'; store = db.getObjectStore(mode), request = data.id ? store.put(data) : store.add(data); request.onsuccess = callback; }); }, getAll: function (callback) { db.open(function () { var store = db.getObjectStore(), cursor = store.openCursor(), data = []; cursor.onsuccess = function (e) { var result = e.target.result; if (result && result !== null) { data.push(result.value); result.continue(); } else { callback(data); } }; }); }, get: function (id, callback) { id = parseInt(id); db.open(function () { var store = db.getObjectStore(), request = store.get(id); request.onsuccess = function (e){ callback(e.target.result); }; }); }, 'delete': function (id, callback) { id = parseInt(id); db.open(function () { var mode = 'readwrite', store, request; store = db.getObjectStore(mode); request = store.delete(id); request.onsuccess = callback; }); }, deleteAll: function (callback) { db.open(function () { var mode, store, request; mode = 'readwrite'; store = db.getObjectStore(mode); request = store.clear(); request.onsuccess = callback; }); } }; window.app = window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// index.db.js
 
;
 
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
 
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
 
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;
 
(function(window){
 
    'use strict';
 
    var db = {
 
        version: 1, // important: only use whole numbers!
 
        objectStoreName: 'tasks',
 
        instance: {},
 
        upgrade: function (e) {
 
            var
                _db = e.target.result,
                names = _db.objectStoreNames,
                name = db.objectStoreName;
 
            if (!names.contains(name)) {
 
                _db.createObjectStore(
                    name,
                    {
                        keyPath: 'id',
                        autoIncrement: true
                    });
            }
        },
 
        errorHandler: function (error) {
            window.alert('error: ' error.target.code);
            debugger;
        },
 
        open: function (callback) {
 
            var request = window.indexedDB.open(
                db.objectStoreName, db.version);
 
            request.onerror = db.errorHandler;
 
            request.onupgradeneeded = db.upgrade;
 
            request.onsuccess = function (e) {
 
                db.instance = request.result;
 
                db.instance.onerror =
                    db.errorHandler;
 
                callback();
            };
        },
 
        getObjectStore: function (mode) {
 
            var txn, store;
 
            mode = mode || 'readonly';
 
            txn = db.instance.transaction(
                [db.objectStoreName], mode);
 
            store = txn.objectStore(
                db.objectStoreName);
 
            return store;
        },
 
        save: function (data, callback) {
 
            db.open(function () {
 
                var store, request,
                    mode = 'readwrite';
 
                store = db.getObjectStore(mode),
 
                request = data.id ?
                    store.put(data) :
                    store.add(data);
 
                request.onsuccess = callback;
            });
        },
 
        getAll: function (callback) {
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];
 
                cursor.onsuccess = function (e) {
 
                    var result = e.target.result;
 
                    if (result &&
                        result !== null) {
 
                        data.push(result.value);
                        result.continue();
 
                    } else {
 
                        callback(data);
                    }
                };
 
            });
        },
 
        get: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    request = store.get(id);
 
                request.onsuccess = function (e){
                    callback(e.target.result);
                };
            });
        },
 
        'delete': function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    mode = 'readwrite',
                    store, request;
 
                store = db.getObjectStore(mode);
 
                request = store.delete(id);
 
                request.onsuccess = callback;
            });
        },
 
        deleteAll: function (callback) {
 
            db.open(function () {
 
                var mode, store, request;
 
                mode = 'readwrite';
                store = db.getObjectStore(mode);
                request = store.clear();
 
                request.onsuccess = callback;
            });
 
        }
    };
 
    window.app = window.app || {};
    window.app.db = db;
 
}(window));

Listing 3: Full source for user interface-specific code (index.ui.js)

JavaScript

// index.ui.js ; (function ($, Modernizr, app) { 'use strict'; $(function(){ if(!Modernizr.indexeddb){ $('#unsupported-message').show(); $('#ui-container').hide(); return; } var $deleteAllBtn = $('#delete-all-btn'), $titleText = $('#title-text'), $notesText = $('#notes-text'), $idHidden = $('#id-hidden'), $clearButton = $('#clear-button'), $saveButton = $('#save-button'), $listContainer = $('#list-container'), $noteTemplate = $('#note-template'), $emptyNote = $('#empty-note'); var addNoTasksMessage = function(){ $listContainer.append( $emptyNote.html()); }; var bindData = function (data) { $listContainer.html(''); if(data.length === 0){ addNoTasksMessage(); return; } data.forEach(function (note) { var m = $noteTemplate.html(); m = m.replace(/{ID}/g, note.id); m = m.replace(/{TITLE}/g, note.title); $listContainer.append(m); }); }; var clearUI = function(){ $titleText.val('').focus(); $notesText.val(''); $idHidden.val(''); }; // select individual item $listContainer.on('click', 'a[data-id]', function (e) { var id, current; e.preventDefault(); current = e.currentTarget; id = $(current).attr('data-id'); app.db.get(id, function (note) { $titleText.val(note.title); $notesText.val(note.text); $idHidden.val(note.id); }); return false; }); // delete item $listContainer.on('click', 'i[data-id]', function (e) { var id, current; e.preventDefault(); current = e.currentTarget; id = $(current).attr('data-id'); app.db.delete(id, function(){ app.db.getAll(bindData); clearUI(); }); return false; }); $clearButton.click(function(e){ e.preventDefault(); clearUI(); return false; }); $saveButton.click(function (e) { var title = $titleText.val(); if (title.length === 0) { return; } var note = { title: title, text: $notesText.val() }; var id = $idHidden.val(); if(id !== ''){ note.id = parseInt(id); } app.db.save(note, function(){ app.db.getAll(bindData); clearUI(); }); }); $deleteAllBtn.click(function (e) { e.preventDefault(); app.db.deleteAll(function () { $listContainer.html(''); addNoTasksMessage(); clearUI(); }); return false; }); app.db.errorHandler = function (e) { window.alert('error: ' e.target.code); debugger; }; app.db.getAll(bindData); }); }(jQuery, Modernizr, window.app));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// index.ui.js
 
;
 
(function ($, Modernizr, app) {
 
    'use strict';
 
    $(function(){
 
        if(!Modernizr.indexeddb){
            $('#unsupported-message').show();
            $('#ui-container').hide();
            return;
        }
 
        var
          $deleteAllBtn = $('#delete-all-btn'),
          $titleText = $('#title-text'),
          $notesText = $('#notes-text'),
          $idHidden = $('#id-hidden'),
          $clearButton = $('#clear-button'),
          $saveButton = $('#save-button'),
          $listContainer = $('#list-container'),
          $noteTemplate = $('#note-template'),
          $emptyNote = $('#empty-note');
 
        var addNoTasksMessage = function(){
            $listContainer.append(
                $emptyNote.html());
        };
 
        var bindData = function (data) {
 
            $listContainer.html('');
 
            if(data.length === 0){
                addNoTasksMessage();
                return;
            }
 
            data.forEach(function (note) {
              var m = $noteTemplate.html();
              m = m.replace(/{ID}/g, note.id);
              m = m.replace(/{TITLE}/g, note.title);
              $listContainer.append(m);
            });
        };
 
        var clearUI = function(){
            $titleText.val('').focus();
            $notesText.val('');
            $idHidden.val('');
        };
 
        // select individual item
        $listContainer.on('click', 'a[data-id]',
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr('data-id');
 
                app.db.get(id, function (note) {
                    $titleText.val(note.title);
                    $notesText.val(note.text);
                    $idHidden.val(note.id);
                });
 
                return false;
            });
 
        // delete item
        $listContainer.on('click', 'i[data-id]',
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr('data-id');
 
                app.db.delete(id, function(){
                    app.db.getAll(bindData);
                    clearUI();
                });
 
                return false;
        });
 
        $clearButton.click(function(e){
            e.preventDefault();
            clearUI();
            return false;
        });
 
        $saveButton.click(function (e) {
 
            var title = $titleText.val();
 
            if (title.length === 0) {
                return;
            }
 
            var note = {
                title: title,
                text: $notesText.val()
            };
 
            var id = $idHidden.val();
 
            if(id !== ''){
                note.id = parseInt(id);
            }
 
            app.db.save(note, function(){
                app.db.getAll(bindData);
                clearUI();
            });
        });
 
        $deleteAllBtn.click(function (e) {
 
            e.preventDefault();
 
            app.db.deleteAll(function () {
                $listContainer.html('');
                addNoTasksMessage();
                clearUI();
            });
 
            return false;
        });
 
        app.db.errorHandler = function (e) {
            window.alert('error: ' e.target.code);
            debugger;
        };
 
        app.db.getAll(bindData);
 
    });
 
}(jQuery, Modernizr, window.app));

Listing 3: Full HTML source (index.html)

JavaScript

<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Introduction to IndexedDB</title> <meta name="description" content="Introduction to IndexedDB"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/css/font-awesome.min.css" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/FontAwesome.otf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.eot" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.svg" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.woff" > <style> h1 { text-align: center; color:#999; } ul li { font-size: 1.35em; margin-top: 1em; margin-bottom: 1em; } ul li.small { font-style: italic; } footer { margin-top: 25px; border-top: 1px solid #eee; padding-top: 25px; } i[data-id] { cursor: pointer; color: #eee; } i[data-id]:hover { color: #c75a6d; } .push-down { margin-top: 25px; } #save-button { margin-left: 10px; } </style> <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr /2.8.2/modernizr.min.js" ></script> </head> <body class="container"> <h1>Tasks</h1> <div id="unsupported-message" class="alert alert-warning" style="display:none;"> <b>Aww snap!</b> Your browser does not support indexedDB. </div> <div id="ui-container" class="row"> <div class="col-sm-3"> <a href="#" id="delete-all-btn" class="btn-xs"> <i class="fa fa-trash-o"></i> Delete All</a> <hr/> <ul id="list-container" class="list-unstyled"></ul> </div> <div class="col-sm-8 push-down"> <input type="hidden" id="id-hidden" /> <input id="title-text" type="text" class="form-control" tabindex="1" placeholder="title" autofocus /><br /> <textarea id="notes-text" class="form-control" tabindex="2" placeholder="text"></textarea> <div class="pull-right push-down"> <a href="#" id="clear-button" tabindex="4">Clear</a> <button id="save-button" tabindex="3" class="btn btn-default btn-primary"> <i class="fa fa-save"></i> Save</button> </div> </div> </div> <footer class="small text-muted text-center">by <a href="" target="_blank">Craig Shoemaker</a> <a href="" target="_blank"> <i class="fa fa-twitter"></i></a> </footer> <script id="note-template" type="text/template"> <li> <i data-id="{ID}" class="fa fa-minus-circle"></i> <a href="#" data-id="{ID}">{TITLE}</a> </li> </script> <script id="empty-note" type="text/template"> <li class="text-muted small">No tasks</li> </script> <script src="//ajax.googleapis.com/ajax/libs /jquery/1.11.1/jquery.min.js"></script> <script src="index.db.js" type="text/javascript"></script> <script src="index.ui.js" type="text/javascript"></script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!doctype html>
<html lang="en-US">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Introduction to IndexedDB</title>
        <meta name="description"
              content="Introduction to IndexedDB">
        <meta name="viewport"
              content="width=device-width, initial-scale=1">
        <link rel="stylesheet"
              href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff" >
        <style>
            h1 {
                text-align: center;
                color:#999;
            }
 
            ul li {
                font-size: 1.35em;
                margin-top: 1em;
                margin-bottom: 1em;
            }
 
            ul li.small {
                font-style: italic;
            }
 
            footer {
                margin-top: 25px;
                border-top: 1px solid #eee;
                padding-top: 25px;
            }
 
            i[data-id] {
                cursor: pointer;
                color: #eee;
            }
 
            i[data-id]:hover {
                color: #c75a6d;
            }
 
            .push-down {
                margin-top: 25px;
            }
 
            #save-button {
                margin-left: 10px;
            }
        </style>
        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr
/2.8.2/modernizr.min.js" ></script>
    </head>
    <body class="container">
        <h1>Tasks</h1>
        <div id="unsupported-message"
             class="alert alert-warning"
             style="display:none;">
            <b>Aww snap!</b> Your browser does not support indexedDB.
        </div>
        <div id="ui-container" class="row">
            <div class="col-sm-3">
 
                <a href="#" id="delete-all-btn" class="btn-xs">
                    <i class="fa fa-trash-o"></i> Delete All</a>
 
                <hr/>
 
                <ul id="list-container" class="list-unstyled"></ul>
 
            </div>
            <div class="col-sm-8 push-down">
 
                <input type="hidden" id="id-hidden" />
 
                <input
                       id="title-text"
                       type="text"
                       class="form-control"
                       tabindex="1"
                       placeholder="title"
                       autofocus /><br />
 
                <textarea
                          id="notes-text"
                          class="form-control"
                          tabindex="2"
                          placeholder="text"></textarea>
 
                <div class="pull-right push-down">
 
                    <a href="#" id="clear-button" tabindex="4">Clear</a>
 
                    <button id="save-button"
                            tabindex="3"
                            class="btn btn-default btn-primary">
                                <i class="fa fa-save"></i> Save</button>
                </div>
            </div>
        </div>
        <footer class="small text-muted text-center">by
            <a href="http://craigshoemaker.net" target="_blank">Craig Shoemaker</a>
            <a href="http://twitter.com/craigshoemaker" target="_blank">
                <i class="fa fa-twitter"></i></a>
        </footer>
        <script id="note-template" type="text/template">
            <li>
                <i data-id="{ID}" class="fa fa-minus-circle"></i>
                <a href="#" data-id="{ID}">{TITLE}</a>
            </li>
        </script>
        <script id="empty-note" type="text/template">
            <li class="text-muted small">No tasks</li>
        </script>
        <script src="//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js"></script>
        <script src="index.db.js" type="text/javascript"></script>
        <script src="index.ui.js" type="text/javascript"></script>
    </body>
</html>

赞 1 收藏 评论

在 二〇〇八 年 1月 18 日,W3C宣布弃用Web SQL数据库标准。那也正是提出网络开采人士不要再使用这种技艺了,该标准也不会再拿走新的立异,并且不鼓劲浏览器经销商扶植该技巧。

至于小编:cucr

乐百家前段 9

搜狐博客园:@hop_ping 个人主页 · 笔者的篇章 · 17

乐百家前段 10

 

代表的是 IndexedDB,本学科的主题是开采人员应采用这种数据存款和储蓄在客户端上囤积数据并实行操作。

 

各大主流浏览器(满含Chrome浏览器、Safari、Opera等)和大概全体基于Webkit的位移设备均扶持WebSQL,並且很有相当的大希望在可预知的今后无冕提供支撑。

 

先决条件

该示例使用命名空间封装数据库逻辑。 

 

[html] 

var html5rocks = {};  html5rocks.indexedDB = {};  var html5rocks = {};

html5rocks.indexedDB = {};异步和事务性

在大超级多状态下,倘若您使用的是索引型数据库,那么就能够采取异步API。异步API是非窒碍系统,因而不会经过重回值获得数量,而是获得传递到钦点回调函数的数目。

 

因而 HTML 接济IndexedDB是事务性的。在事情之外是敬敏不谢实行命令或展开指针的。事务包蕴如下类型:读/写作业、只读事务和快速照相事务。在本教程中,我们应用的是读/写作业。

 

第 1步:张开数据库

你必得先打开数据库,能力对其进展操作。 

 

[html]

html5rocks.indexedDB.db = null;    html5rocks.indexedDB.open = function() {    var request = indexedDB.open("todos");      request.onsuccess = function(e) {      html5rocks.indexedDB.db = e.target.result;      // Do some more stuff in a minute    };      request.onfailure = html5rocks.indexedDB.onerror;  };  html5rocks.indexedDB.db = null;

 

html5rocks.indexedDB.open = function() {

  var request = indexedDB.open("todos");

 

  request.onsuccess = function(e) {

    html5rocks.indexedDB.db = e.target.result;

    // Do some more stuff in a minute

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

};我们已展开名称叫“todos”的数据库,并已将其分配给html5rocks.indexedDB对象中的db变量。以后我们得以在任何课程中接收此变量来引用大家的数据库。

 

第 2步:创造对象存储

你必须要在“SetVersion”事务内创建对象存款和储蓄。笔者还一直不介绍setVersion,那是一个老大首要的办法,那是代码中天下无双能够供您制造对象存款和储蓄和目录的地点。

本文由乐百家前段发布,转载请注明来源:HTML5地面存储——IndexedDB