>

前端的数据库,深入解析HTML5中的IndexedDB索引数据

- 编辑:金沙国际平台登录 -

前端的数据库,深入解析HTML5中的IndexedDB索引数据

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

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁绝转发!
塞尔维亚语出处:www.codemag.com。应接插足翻译组。

应用程序需求多少。对大部分Web应用程序来讲,数据在服务器端组织和管制,顾客端通过互连网伏乞获取。随着浏览器变得愈加有力量,因而可挑选在浏览器存款和储蓄和调控应用程序数据。

本文向你介绍名称为IndexedDB的浏览器端文档数据库。使用lndexedDB,你能够由此惯于在劳动器端数据库大约同样的不二秘技开创、读取、更新和删除大批量的笔录。请使用本文中可专门的职业的代码版本去感受,完整的源代码可以因此GitHub库找到。

读到本学科的最终时,你将熟识IndexedDB的基本概念以及如何促成贰个使用IndexedDB实施总体的CRUD操作的模块化JavaScript应用程序。让大家有一点点亲密IndexedDB并开头吧。

什么是IndexedDB

寻常的话,有二种差异类别的数据库:关系型和文书档案型(也称之为NoSQL或对象)。关全面据库如SQL Server,MySQL,Oracle的数额存储在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个体对象存款和储蓄。IndexedDB是三个文书档案数据库,它在一起内放置浏览器中的三个沙盒遭受中(强制依据(浏览器)同源计谋)。图1出示了IndexedDB的数量,彰显了数据库的构造

图片 1

图1:开采者工具查看四个object store

不论什么事的IndexedDB API请参见完整文书档案

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

那篇小说首要介绍了浓厚深入分析HTML5中的IndexedDB索引数据库,包蕴事务锁等基本成效的连锁应用示例,须求的爱侣能够参照下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5 WEB应用在客户浏览器端存储数据。对于使用来说IndexedDB特别强劲、有用,能够在顾客端的chrome,IE,Firefox等WEB浏览器中蕴藏多量数量,上边简介一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的多少存款和储蓄,能够在顾客端存款和储蓄、操作数据,能够使利用加载地更加快,更加好地响应。它区别于关系型数据库,拥有数据表、记录。它影响着大家布署和开创应用程序的点子。IndexedDB 成立有数据类型和简易的JavaScript漫长对象的object,种种object能够有目录,使其立见成效地查询和遍历整个集结。本文为您提供了怎么样在Web应用程序中运用IndexedDB的诚实事例。
 
开始 大家必要在施行前包括上面后置代码

JavaScript Code复制内容到剪贴板

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

 
打开IndexedDB 在开立数据库从前,大家先是须求为数据库创制数量,假设大家有如下的客户音信:

JavaScript Code复制内容到剪贴板

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

今昔我们需求用open()方法打开我们的数据库:

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”作为key帕特h,这几个值在目的存储中是唯一的,大家必得保险该“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个参数(第贰个和第三个是可选的)。 首个是我们要管理的指标存款和储蓄的列表,第三个钦赐大家是否要只读/读写,第1个是本子变化。
 
从表中读取数据 get()方法用于从目标存款和储蓄中搜寻数据。 大家此前已经安装对象的id作为的keyPath,所以get()方法将追寻具有同样id值的目的。 上面包车型地铁代码将重临大家命名字为“Bidulata”的对象:

JavaScript Code复制内容到剪贴板

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

 
从表中读取全体数据
下边包车型大巴艺术搜索表中的全体数据。 这里大家使用游标来查找对象存储中的全体数据:

JavaScript Code复制内容到剪贴板

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

该openCursor()用于遍历数据库中的七个记录。 在continue()函数中继续读取下一条记下。
去除表中的记录 上边包车型地铁格局从目的中删除记录。

JavaScript Code复制内容到剪贴板

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

我们要将目的的keyPath作为参数字传送递给delete()方法。
 
终极代码
上面的艺术从目的源中删除一条记下:

JavaScript Code复制内容到剪贴板

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

localStorage是不带lock功用的。那么要兑现前端的数量分享並且须要lock功用那就供给使用其余本储存格局,比如indexedDB。indededDB使用的是事务管理的建制,那实在便是lock功用。
  做这一个测验必要先轻松的包裹下indexedDB的操作,因为indexedDB的连接比较费劲,何况三个测量试验页面都须要用到

JavaScript Code复制内容到剪贴板

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

把localStorage换到了indexedDB事务管理。不过结果就差别

图片 2

测量检验的时候b.html中可能不会应声有出口,因为indexedDB正忙着处理a.html东西,b.html事务丢在了业务丢队列中等待。可是无论怎样,输出结果也不会是1以此值。因为indexedDB的非常的小管理单位是工作,并非localStorage那样以表达式为单位。那样一旦把lock和unlock之间必要管理的事物归入二个业务中就可以完毕。其他,浏览器对indexedDB的支撑比不上localStorage,所以利用时还得思考浏览器宽容。

那篇小说首要介绍了入木四分深入分析HTML5中的IndexedDB索引数据库,包含事务锁等基本作用的相关使...

设计标准

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名字的数组到创建工作限制的函数来定义。

开创工作的第2个参数是专业方式。当呼吁贰个事务时,必需调控是遵照只读依旧读写形式诉求访问。事务是能源密集型的,所以只要您没有须要改造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和金立部分补助。即便那些列表的拥护者是动人心弦的,但它并未有报告全部有趣的事。

图片 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是或不是切合自个儿的应用程序?

近日最珍视的标题:“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会讲评),为应用程序提供特定于数据库的逻辑。因而,如您所见本文后边的一部分中定义的函数,想想父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的名称和你想使用的数据库版本号。

一经必要的实例可用,第一步要开展的做事是设置错误管理程序和晋升函数。记住,当数据库被打开时,固然脚本央浼比浏览器里越来越高版本的数据库(也许一旦数据库不真实),进级函数运转。可是,要是诉求的数据库版本相配当前数据库版本同时没错误,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的左右文中使用。那篇小说发布时,还未有浏览器实现的共同格式的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

本文由首页发布,转载请注明来源:前端的数据库,深入解析HTML5中的IndexedDB索引数据