HTML5 IndexedDB

HTML5 IndexedDB

前面二个的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 –
cucr
翻译,黄利民
校稿。未经许可,制止转发!
西班牙语出处:www.codemag.com。招待到场翻译组。

应用程序供给多少。对大大多Web应用程序来讲,数据在劳务器端组织和治本,客商端通过互联网央求获取。随着浏览器变得越发有技巧,由此可选择在浏览器存款和储蓄和垄断(monopoly卡塔尔(英语:State of Qatar)应用程序数据。

正文向您介绍名称叫IndexedDB的浏览器端文书档案数据库。使用lndexedDB,你可以通过惯于在服务器端数据库差没多少千篇蓬蓬勃勃律的主意创制、读取、更新和删除大批量的记录。请使用本文中可职业的代码版本去体验,完整的源代码能够通过GitHub库找到。

读到本课程的结尾时,你将熟识IndexedDB的基本概念以至哪些促成三个用到IndexedDB执行总体的CRUD操作的模块化JavaScript应用程序。让大家略略亲密IndexedDB并开首吧。

什么是IndexedDB

诚如的话,有二种不相同体系的数据库:关系型和文书档案型(也叫做NoSQL或对象卡塔尔(قطر‎。关周详据库如SQL
Server,MySQL,Oracle的数目存款和储蓄在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个体对象存款和储蓄。IndexedDB是八个文书档案数据库,它在完全内放置浏览器中的贰个沙盒境况中(强制依照(浏览器)同源攻略卡塔尔国。图1出示了IndexedDB的数据,体现了数据库的协会

澳门新萄京8522 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. 澳门新萄京8522,    
  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(卡塔尔(英语:State of Qatar)方法是用来钦定大家想要实行事务处理的靶子存款和储蓄。
transaction(卡塔尔(قطر‎方法选拔3个参数(第2个和第几个是可选的)。
第多少个是我们要管理的指标存款和储蓄的列表,第三个钦赐大家是或不是要只读/读写,第八个是本子变化。
 
从表中读取数据 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(卡塔尔(英语:State of Qatar)函数中世袭读取下一条记下。
剔除表中的笔录 下边的不二等秘书籍从目的中删去记录。

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(卡塔尔(英语:State of Qatar)方法。
 
末尾代码
上面包车型客车艺术从目的源中删除一条记下:

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事务管理。可是结果就不相同

澳门新萄京8522 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;
//连接数据库(张开句柄卡塔尔(英语:State of Qatar)
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事件。

澳门新萄京8522 3

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

负有与数据库的并行开头于二个开垦的号召。试图张开数据库时,您必需传递叁个被号令数据库的版本号的整数值。在开垦央浼时,浏览器比较你传入的用来展开央求的版本号与实际数据库的版本号。要是所央浼的版本号高于浏览器中当前的版本号(只怕以后尚无存在的数据库卡塔尔,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和华为部分援助。即使这么些列表的跟随者是激动人心的,但它从不报告全数传说。

澳门新萄京8522 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显示了正在编纂职务时的应用程序。

澳门新萄京8522 5

图4:空白的天职应用程序

澳门新萄京8522 6

图5:职务列表

澳门新萄京8522 7

图6:删除职务

澳门新萄京8522 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的名字到数组中。事务函数的第1个参数是三个方式。

假若事情须要可用,您就足以经过传递必要的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%20/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 收藏
评论

在 二〇〇八 年 十一月 18 日,W3C宣布弃用Web
SQL数据库规范。那约等于建议网络开辟人士不要再选拔这种技艺了,该标准也不会再拿到新的换代,而且不慰勉浏览器代理商支持该本领。

有关小编:cucr

澳门新萄京8522 9

博客园网易:@hop_ping
个人主页 ·
小编的篇章 ·
17

澳门新萄京8522 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,那是两个格外首要的格局,那是代码中唯生龙活虎能够供你创造对象存款和储蓄和目录的地点。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图