大发体育娱乐在线-大发体育娱乐官方网站-大发体育娱乐登录网址
做最好的网站

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

来源:http://www.dfwstonefabricators.com 作者:前端学习 人气:132 发布时间:2019-09-24
摘要:前端的数据库:IndexedDB入门 2014/12/27 · 未分类 · IndexedDB 本文由 伯乐在线 -cucr翻译,黄利民校稿。未经许可,禁止转发! 土耳其共和国语出处:www.codemag.com。招待参加翻译组。 应用程

前端的数据库: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”作为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个参数(第3个和第八个是可选的)。 第二个是大家要管理的对象存储的列表,第一个钦赐我们是不是要只读/读写,第多个是本子变化。
 
从表中读取数据 get()方法用于从指标存款和储蓄中查找数据。 我们事先曾经安装对象的id作为的key帕特h,所以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,所以使用时还得思虑浏览器包容。

那篇小说主要介绍了深入深入分析HTML第55中学的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名字的数组到制造专门的工作限制的函数来定义。

创建工作的第4个参数是事情格局。当呼吁贰个事务时,必需决定是依照只读仍旧读写情势央浼访问。事务是能源密集型的,所以一旦你无需更动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索引数据库,前端的数据

关键词:

最火资讯