浓重深入深入分析HTML5中的IndexedDB索引数据库,

2019-12-07 23:37栏目:WRB前端

前端的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁止转载!
日文出处:www.codemag.com。应接参预翻译组。

应用程序须要多少。对相当多Web应用程序来讲,数据在劳动器端协会和处理,客商端通过互连网乞请获取。随着浏览器变得更为有力量,由此可接受在浏览器存储和操纵应用程序数据。

正文向您介绍名叫IndexedDB的浏览器端文书档案数据库。使用lndexedDB,你能够由此惯于在服务器端数据库大概千篇大器晚成律的法子开创、读取、更新和删除多量的笔录。请使用本文中可职业的代码版本去体会,完整的源代码能够透过GitHub库找到。

读到本课程的末尾时,你将熟练IndexedDB的基本概念以至哪些落实三个用到IndexedDB实施总体的CRUD操作的模块化JavaScript应用程序。让大家多少亲呢IndexedDB并初阶吧。

什么是IndexedDB

貌似的话,有二种不一致类别的数据库:关系型和文书档案型(也称之为NoSQL或对象卡塔尔(英语:State of Qatar)。关全面据库如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(卡塔尔(英语: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事务管理。但是结果就分歧

图片 2

测量试验的时候b.html中恐怕不会应声有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了业务丢队列中等待。但是无论怎么着,输出结果也不会是1那么些值。因为indexedDB的非常小处理单位是业务,实际不是localStorage那样以表明式为单位。那样只要把lock和unlock之间供给管理的事物归入三个事情中就可以落成。别的,浏览器对indexedDB的支撑不比localStorage,所以利用时还得思考浏览器宽容。

那篇文章主要介绍了浓烈深入分析HTML5中的IndexedDB索引数据库,富含事务锁等基本效能的相关使...

设计标准

IndexedDB的构造很像在有的流行的劳务器端NOSQL数据库完结中的设计规范类型。面向对象数据经过object stores(对象仓库)进行长久化,全部操作基于央浼同临时候在事情限定内实行。事件生命周期使您能够支配数据库的安排,错误通过荒唐冒泡来使用API管理。

对象酒馆

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 部分开展了详细研究。

据悉诉求

截止这里,有三个往往现身的宗旨,您只怕早就注意到。对数据库的每一遍操作,描述为经过叁个呼吁展开数据库,访谈三个object store,再持续。IndexedDB API天生是基于央求的,那也是API异步天性提醒。对于你在数据库施行的每一趟操作,你必须首先为那些操作创造一个伸手。当呼吁完结,你能够响应由伏乞结果发生的风浪和不当。

本文完毕的代码,演示了怎么着行使央求张开数据库,创制一个业务,读取object store的开始和结果,写入object store,清空object store。

张开数据库的伏乞生命周期

IndexedDB使用事件生命周期管理数据库的开采和配置操作。图2演示了叁个开发的央浼在早晚的景况下发出upgrade need事件。

图片 3

图2:IndexedDB打开乞求的生命周期

有着与数据库的竞相最初于贰个张开的央求。试图张开数据库时,您必需传递壹个被呼吁数据库的版本号的整数值。在开荒央求时,浏览器比较你传入的用来打开需要的版本号与实际数据库的版本号。假若所乞求的版本号高于浏览器中当前的版本号(只怕以往尚无存在的数据库卡塔尔(قطر‎,upgrade needed事件触发。在uprade need事件之间,你有时机通过丰裕或移除stores,键和索引来操纵object stores。

比方所乞请的数据库版本号和浏览器的脚下版本号相符,只怕晋级进程做到,三个打开的数据库将回来给调用者。

荒诞冒泡

不容争辩,不常候,乞求可能不会按预期完结。IndexedDB API通过荒唐冒泡效果来救助追踪和管理漏洞超多。若是一个一定的乞求蒙受错误,你能够尝试在号令对象上管理错误,大概您能够允许错误通过调用栈冒泡向上传递。那个冒泡本性,使得你无需为种种须求完毕特定错误管理操作,而是能够选拔只在一个越来越高端别上加多错误管理,它给您二个时机,保持你的错误管理代码简洁。本文中得以完成的例子,是在二个高端别管理错误,以便越来越细粒度操作发生的别的不当冒泡到通用的错误管理逻辑。

浏览器支持

恐怕在开辟Web应用程序最注重的主题素材是:“浏览器是或不是扶助自个儿想要做的?“就算浏览器对IndexedDB的支撑在继续拉长,接收率并不是我们所企望的那样布满。图3出示了caniuse.com网址的告知,支持IndexedDB的为66%多一丝丝。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全支持IndexedDB,Internet Explorer和OPPO部分辅助。固然那个列表的拥护者是激动人心的,但它并未有报告全体传说。

图片 4

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

只有充足新本子的Safari和iOS Safari 协助IndexedDB。据caniuse.com呈现,那只占大致0.01%的大地浏览器选取。IndexedDB不是一个您感觉能够道理当然是那样的获得接济的现代Web API,但是你将急速会这么以为。

另风度翩翩种接收

浏览器补助本地数据库并非从IndexedDB才开首兑现,它是在WebSQL贯彻之后的后生可畏种新措施。雷同IndexedDB,WebSQL是一个客户端数据库,但它当作三个关全面据库的兑现,使用构造化查询语言(SQL卡塔尔(英语:State of Qatar)与数据库通讯。WebSQL的历史充满了波折,但底线是从未主流的浏览器商家对WebSQL继续帮助。

假若WebSQL实际上是多个放任的工夫,为何还要提它吗?有意思的是,WebSQL在浏览器里得到稳步的支撑。Chrome, Safari, iOS Safari, and Android 浏览器都支持。此外,而不是那一个浏览器的最新版本才提供支撑,相当多那个新式最佳的浏览器在此以前的本子也足以支撑。有意思的是,假如您为WebSQL增加辅助来支持IndexedDB,你突然意识,多数浏览器厂家和本子成为辅助浏览器内置数据库的某种化身。

因此,倘让你的应用程序真正要求二个客户端数据库,你想要到达的最高端其他利用恐怕,当IndexedDB不可用时,只怕你的应用程序大概看起来要求选择选取WebSQL来扶持顾客端数据结构。即使文书档案数据库和关全面据库管理数据有生硬的区别,但若是你有科学的用空想来欺骗别人,就能够采用本地数据库营造贰个应用程序。

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存款和储蓄数据的模块化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会评说卡塔尔(英语:State of Qatar),为应用程序提供特定于数据库的逻辑。由此,如您所见本文后边的一些中定义的函数,用脑筋想父db对象活动,但全体此外职能都是db对象的分子。完整的数据库模块列表见项目清单2。

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的名号和你想利用的数据库版本号。

如果乞请的实例可用,第一步要举办的劳作是安装错误管理程序和晋升函数。记住,当数据库被打开时,如若脚本诉求比浏览器里越来越高版本的数据库(也许意气风发旦数据库不设有卡塔尔(英语:State of Qatar),进级函数运维。然则,要是央浼的数据库版本相配当前数据库版本相同的时候未有不当,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的Web应用程序具备强盛的客户端数据的会见手艺。

在大多数情状下,全部针对IndexedDB编写的代码是天生基于乞请和异步的。官方正规有同步API,不过这种IndexedDB只契合web worker的内外文中使用。那篇作品发表时,还不曾浏览器实现的后生可畏Doug式的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 收藏 评论

至于我:cucr

图片 9

和讯今日头条:@hop_ping 个人主页 · 作者的稿子 · 17

图片 10

版权声明:本文由威尼斯人app发布于WRB前端,转载请注明出处:浓重深入深入分析HTML5中的IndexedDB索引数据库,