当前位置: 56net亚洲必嬴 > Web前端 > 正文

HTML5 IndexedDB

时间:2019-11-01 12:34来源:Web前端
前端的数据库:IndexedDB入门 2014/12/27 · 未分类 · IndexedDB 本文由 伯乐在线 -cucr翻译,黄利民校稿。未经许可,禁止转发! 塞尔维亚共和国(Republic of Serbia)语出处:www.codemag.com。招待参

前端的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁止转发!
塞尔维亚共和国(Republic of Serbia)语出处: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()方法展开我们的数据库:

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个参数(第一个和第七个是可选的)。 第七个是大家要管理的指标存款和储蓄的列表,首个内定我们是或不是要只读/读写,第八个是本子变化。
 
从表中读取数据 get()方法用于从目的存储中寻找数据。 大家事先早已安装对象的id作为的keyPath,所以get()方法将追寻具备相仿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名字的数组到创建专门的学问约束的函数来定义。

创制工作的第二个参数是事情方式。当倡议二个事务时,必须调控是依照只读照旧读写情势要求访问。事务是能源密集型的,所以意气风发旦你没有需求校正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展开伏乞的生命周期

装有与数据库的交互开端于二个开垦的乞请。试图打开数据库时,您必得传递二个被呼吁数据库的版本号的整数值。在展开央求时,浏览器相比你传入的用于展开央求的版本号与实际数据库的版本号。假若所诉求的版本号高于浏览器中当前的版本号(大概以后尚未存在的数据库),upgrade needed事件触发。在uprade need事件之间,你有空子通过抬高或移除stores,键和索引来垄断(monopoly)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和红米部分援助。就算那么些列表的拥护者是心满意足的,但它并未告诉全体传说。

图片 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)有的时候叫做差异的名字。有时能够见到如此的代码组织措施,它称为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 收藏 评论

在 二〇〇九 年 7月 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,那是二个可怜关键的点子,这是代码中独一能够供你成立对象存款和储蓄和目录的位置。

编辑:Web前端 本文来源:HTML5 IndexedDB

关键词:

  • 上一篇:没有了
  • 下一篇:没有了