深深解析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是多个文书档案数据库,它在一点一滴内放置浏览器中的2个沙盒环境中(强制依据(浏览器)同源攻略)。图一来得了IndexedDB的数目,展现了数据库的结构

图片 1

图1:开辟者工具查看多少个object
store

整整的IndexedDB API请参见完整文书档案

深入解析HTML5中的IndexedDB索引数据库,html伍indexeddb

那篇作品首要介绍了入木三分解析HTML5中的IndexedDB索引数据库,包涵事务锁等基本功用的相关应用示例,需求的爱人能够参见下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML五WEB应用在用户浏览器端存款和储蓄数据。对于利用来讲IndexedDB非凡庞大、有用,可以在客户端的chrome,IE,Firefox等WEB浏览器中贮存多量数目,上面简介一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML伍新的数码存款和储蓄,能够在客户端存款和储蓄、操作数据,能够使应用加载地更加快,更加好地响应。它分裂于关系型数据库,具有数据表、记录。它影响着大家安顿和创造应用程序的方法。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”的数据库是不是早已存在,假若存在则展开它,不然创设新的数据库。
二.次之个参数是数据库的版本,用于用户更新数据库结构。
 
onSuccess处理 产生成功事件时“onSuccess”被触发,假若具有成功的请求都在此处理,我们得以经过赋值给db变量保存请求的结果供现在使用。
 
onerror的处理程序 发生错误事件时“onerror”被触发,纵然张开数据库的经过中败诉。
 
Onupgradeneeded处理程序 即使您想翻新数据库(创造,删除或修改数据库),那么您不能不兑现onupgradeneeded处理程序,使您能够在数据库中做任何改换。
在“onupgradeneeded”处理程序中是足以改造数据库的构造的绝无仅有地方。
 
创设和增进数据到表:
IndexedDB使用对象存款和储蓄来存款和储蓄数据,而不是透过表。
每当3个值存款和储蓄在目的存储中,它与几个键相关联。
它同意我们制造的别的对象存款和储蓄索引。
索引允许咱们走访存款和储蓄在指标存款和储蓄中的值。
上边包车型大巴代码呈现了哪些创立对象存储并插入预先准备好的数据:

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()方法创立三个目的存款和储蓄。 此方法接受五个参数:

  • 存储的称谓和参数对象。
    在此间,大家有3个名字为”users”的指标存款和储蓄,并定义了keyPath,那是指标唯1性的性质。
    在那里,大家利用“id”作为keyPath,那些值在指标存储中是绝无仅有的,大家必须保证该“ID”的性格在指标存款和储蓄中的每种对象中设有。
    1旦创造了对象存款和储蓄,我们可以开头应用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()方法接受一个参数(第二个和第多少个是可选的)。
第三个是我们要处理的指标存款和储蓄的列表,第三个钦定我们是或不是要只读/读写,第多少个是本子变化。
 
从表中读取数据 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. }  

我们要将指标的key帕特h作为参数字传送递给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那样以说明式为单位。那样1旦把lock和unlock之间必要处理的东西放入三个政工中就能够完毕。此外,浏览器对indexedDB的协助不比localStorage,所以选取时还得惦念浏览器包容。

那篇作品首要介绍了深刻解析HTML5中的IndexedDB索引数据库,包含事务锁等基本作用的连锁使…

简介

设计规范

IndexedDB的架构很像在有的流行的劳务器端NOSQL数据库达成中的设计规范类型。面向对象数据经过object
stores(对象商旅)举办持久化,全部操作基于请求同时在事情限制内施行。事件生命周期使您可知支配数据库的安顿,错误通过荒谬冒泡来使用API管理。

IndexedDB是HTML5中的新扩大效益。网络数据库托管并留存在用户的浏览器内。只要让开垦人士通过抬高的询问功效创设应用,就能够预言到,将汇合世能够同时在线和离线使用的最新网络使用。

指标仓库

object
store是IndexedDB数据库的基本功。要是您使用过关全面据库,经常能够将object
store等价于三个数据库表。Object
stores包蕴三个或三个目录,在store中依照壹对键/值操作,那提供一种高效牢固数据的点子。

当你安排二个object
store,你不可能不为store选用一个键。键在store中能够以“in-line”或“out-of-line”的法子存在。in-line键通过在数据对象上引用path来维系它在object
store的唯一性。为了注解这点,想想2个总结电子邮件地址属性Person对象。您能够配备你的store使用in-line键emailAddress,它能担保store(持久化对象中的数据)的唯一性。别的,out-of-line键通过单独于数据的值识别唯壹性。在那种气象下,你能够把out-of-line键比作2个平头值,它(整数值)在关周密据库中担任记录的主键。

图1显得了义务数据保存在职分的object
store,它利用in-line键。在那些案例中,键对应于对象的ID值。

 

根据事务

不一样于一些思想的关周详据库的兑现,每贰个对数据库操作是在1个作业的内外文中实施的。事务限制3遍影响1个或多少个object
stores,你通过传播三个object store名字的数组到创造工作限制的函数来定义。

制造职业的第一个参数是业务形式。当呼吁二个事务时,必须调控是鲁人持竿只读还是读写格局请求访问。事务是能源密集型的,所以假若您不供给改变data
store中的数据,你只供给以只读形式对object stores集合进行呼吁访问。

清单2示范了如何利用合适的方式创设二个作业,并在那片作品的 Implementing
Database-Specific Code
 部分举办了详尽座谈。

IndexedDB是什么?

听他们讲请求

直到那里,有四个往往出现的宗旨,您可能早已注意到。对数据库的历次操作,描述为经过二个呼吁展开数据库,访问三个object
store,再持续。IndexedDB
API天生是基于请求的,那也是API异步性情提醒。对于你在数据库施行的每一回操作,你必须首先为那一个操作创制3个伸手。当呼吁完结,你能够响应由请求结果产生的风浪和不当。

正文实现的代码,演示了何等选择请求展开数据库,创制多个工作,读取object
store的内容,写入object store,清空object store。

IndexedDB是指标存款和储蓄,它差异于带有表格(包括行和列的会合)的关周密据库。那是2个首要的一直差异,并且会潜移默化您设计和创设利用的诀窍。

开发数据库的请求生命周期

IndexedDB使用事件生命周期管理数据库的开发和布局操作。图2示范了二个张开的伸手在一定的条件下发生upgrade
need事件。

图片 3

图二:IndexedDB展开请求的生命周期

持有与数据库的竞相先导于贰个开垦的伸手。试图展开数据库时,您必须传递一个被呼吁数据库的本子号的整数值。在张开请求时,浏览器相比你传入的用来张开请求的版本号与事实上数据库的版本号。假设所请求的版本号高于浏览器中当前的版本号(也许未来平昔不存在的数据库),upgrade
needed事件触发。在uprade
need事件时期,你有时机通过抬高或移除stores,键和索引来垄断object stores。

假如所请求的数据库版本号和浏览器的近年来版本号一样,大概升级历程一呵而就,一个开辟的数据库将回到给调用者。

 

谬误冒泡

当然,有时候,请求大概不会按预想完结。IndexedDB
API通过荒谬冒泡效果来帮助追踪和管制不当。如若多少个特定的伸手遇到错误,你可以尝尝在呼吁对象上处理错误,或然你可以允许错误通过调用栈冒泡向上传递。这么些冒泡本性,使得你不需求为各种请求完毕特定错误处理操作,而是能够选拔只在3个越来越高档别上增多错误处理,它给你3个火候,保持你的错误处理代码简洁。本文中贯彻的例子,是在二个高端别处理错误,以便越来越细粒度操作产生的其他不当冒泡到通用的错误处理逻辑。

在观念的关周详据存款和储蓄中,我们有四个“待办事项”的表格,当中各行存储了用户待办事项数据的联谊,而各列则是数码的命名类型。要插入数据,经常选择如下语义:INSERTINTO
Todo(id, data, update_time) VALUES (1, “Test”,”01/01/2010″);

浏览器帮忙

兴许在付出Web应用程序最要害的标题是:“浏览器是不是帮忙笔者想要做的?“固然浏览器对IndexedDB的补助在此起彼伏增加,选取率并不是我们所愿意的那么广泛。图叁突显了caniuse.com网址的报告,帮忙IndexedDB的为66%多一丢丢。最新版本的银狐,Chrome,Opera,Safar,iOS
Safari,和Android完全帮忙IndexedDB,Internet
Explorer和BlackBerry部分支持。即使这么些列表的协助者是激动的,但它从未告诉全部传说。

图片 4

图叁:浏览器对IndexedDB的援助,来自caniuse.com

唯有可怜新本子的Safari和iOS Safari
匡助IndexedDB。据caniuse.com展现,那只占大概0.01%的环球浏览器选择。IndexedDB不是三个您认为能够理所当然得到帮助的今世Web
API,但是你将高速会这么感觉。

 

另一种选取

浏览器援助地点数据库并不是从IndexedDB才起来实现,它是在WebSQL落到实处之后的1种新点子。类似IndexedDB,WebSQL是2个客户端数据库,但它看做3个关周全据库的兑现,使用结构化查询语言(SQL)与数据库通讯。WebSQL的历史充满了弯曲,但底线是从未主流的浏览器商家对WebSQL继续辅助。

若果WebSQL实际上是三个抛弃的手艺,为啥还要提它呢?有意思的是,WebSQL在浏览器里拿走稳步的支撑。Chrome,
Safari, iOS Safari, and
Android 浏览器都援助。其余,并不是这一个浏览器的新颖版本才提供支撑,多数这个最新最佳的浏览器从前的版本也足以协理。风趣的是,即使您为WebSQL增多帮忙来支撑IndexedDB,你突然发现,大多浏览器厂家和本子成为支撑浏览器内置数据库的某种化身。

为此,要是您的应用程序真正供给三个客户端数据库,你想要达到的最高等其他运用也许,当IndexedDB不可用时,大概你的应用程序恐怕看起来必要选用使用WebSQL来支撑客户端数据架构。尽管文档数据库和关周详据库管理数据有醒目标差别,但万壹您有不易的架空,就足以应用本地数据库创设贰个应用程序。

IndexedDB的不相同之处在于,您能够创造有些项目数据的靶子存储,然后只需将JavaScript对象留存在该存款和储蓄中就能够。各样对象存款和储蓄都能够有目录的相会,那样就能张开高效的询问和迭代。

IndexedDB是还是不是符合自己的应用程序?

现行反革命最重大的标题:“IndexedDB是不是符合小编的应用程序?“像过去一律,答案是必然的:“视意况而定。“首先当你打算在客户端保存数据时,你会考虑HTML伍本土存储。本地存储得到大面积浏览器的支持,有卓殊轻便使用的API。轻松有其优势,但其劣势是心有余而力不足支撑复杂的物色战术,存款和储蓄大量的数据,并提供业务帮助。

IndexedDB是贰个数据库。所以,当你想为客户端做出决定,思量你什么样在服务端采纳3个持久化介质的数据库。你也许会问本人有些难题来提携调节客户端数据库是或不是适合你的应用程序,包涵:

  • 您的用户通过浏览器访问您的应用程序,(浏览器)帮助IndexedDB API吗 ?
  • 你需求仓库储存多量的数目在客户端?
  • 您须要在2个巨型的多少集合中非常的慢牢固单个数总局?
  • 你的框架结构在客户端必要职业协理呢?

设若你对在那之中的此外问题回复了“是的”,很有非常的大希望,IndexedDB是你的应用程序的叁个很好的候选。

 

使用IndexedDB

于今,你已经有时机熟识了一些的一体化概念,下一步是发端落实基于IndexedDB的应用程序。第3个步骤供给统壹IndexedDB在分歧浏览器的落到实处。您能够很轻松地拉长各个商家性子的选料的检查,同时在window对象上把它们设置为合法对象同样的名称。下边的清单展现了window.indexedDB,window.IDBTransaction,window.IDBKeyRange的尾声结出是怎么都被更新,它们被设置为相应的浏览器的一定实现。

JavaScript

window.indexedDB = window.indexedDB || window.mozIndexedDB ||
window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction =
window.IDBTransaction || window.webkitIDBTransaction ||
window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange ||
window.webkitIDBKeyRange || window.msIDBKeyRange;

1
2
3
4
5
6
7
8
9
10
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;

现行,种种数据库相关的全局对象具有正确的版本,应用程序能够准备使用IndexedDB初叶工作。

IndexedDB 还裁撤了标准查询语言(
SQL)的概念,代替他的是针对性索引的查询,那样能够生出多少个指南针,用于在结果集以内迭代。

运用概述

在本教程中,您将学习怎么成立二个运用IndexedDB存款和储蓄数据的模块化JavaScript应用程序。为了打探应用程序是哪些做事的,参考图四,它描述了职分应用程序处于空白状态。从这里你可以为列表加多新职务。图5显得了录入了多少个职分到系统的镜头。图六呈现怎么删除二个职务,图7呈现了正在编辑任务时的应用程序。

图片 5

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

图片 6

图5:任务列表

图片 7

图六:删除任务

图片 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));

用这么的协会,能够使这一个应用程序的兼具逻辑封装在1个名称为app的单对象上。别的,数据库相关的代码在三个号称db的app子对象上。

本条模块的代码应用IIFE,通过传递window对象来保管模块的熨帖限制。使用use
strict确认保障这么些函数的代码函数是根据(javascript严刻格局)严谨编写翻译规则。db对象作为与数据库交互的兼具函数的重点容器。最终,window对象检查app的实例是还是不是存在,假设存在,模块使用当前实例,假若不存在,则开创3个新对象。一旦app对象成功重临或成立,db对象附加到app对象。

正文的其他部分将代码增添到db对象内(在implementation
here会
讲评),为应用程序提供特定于数据库的逻辑。由此,如您所见本文后边的1部分中定义的函数,想想父db对象活动,但全部此外功效都以db对象的成员。完整的数据库模块列表见清单②。

本课程只是举了贰个实在示例,告诉您针对编写为运用WebSQL
的水土保持应用怎样行使IndexedDB。 

Implementing Database-Specific Code

对数据库的各类操作关联着一个先决条件,即有二个开拓的数据库。当数据库正在被张开时,通过检查数据库版本来推断数据库是不是须要别的退换。上面包车型客车代码显示了模块怎么着追踪当前版本,object
store名、某成员(保存了要是数据库展开请求实现后的数据库当前实例)。

JavaScript

version: 1, objectStoreName: ‘tasks’, instance: {},

1
2
3
version: 1,
objectStoreName: ‘tasks’,
instance: {},

在此处,数据库展开请求产生时,模块请求版本1数据库。要是数据库不存在,恐怕版本小于1,upgrade
needed事件在开拓请求完毕前触发。这一个模块棉被服装置为只利用贰个object
store,所以名字直接定义在此处。最终,实例成员被制造,它用来保存1旦张开请求实现后的数据库当前实例。

接下去的操作是兑现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成员)来创立。

模块的下2个功效是用来捕获错误,错误在模块分歧的伸手创制时冒泡。

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在1个警告框展现其余不当。那一个函数是有意保持简单,对开辟协调,当你学习运用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的称呼和你想选择的数据库版本号。

如若请求的实例可用,第叁步要拓展的干活是设置错误处理程序和提高函数。记住,当数据库被张开时,如若脚本请求比浏览器里越来越高版本的数据库(大概1旦数据库不存在),晋级函数运转。可是,假诺请求的数据库版本相配当前数据库版本同时没错误,success事件触发。

要是全勤成功,张开数据库的实例能够从呼吁实例的result属性得到,这些实例也缓存到模块的实例属性。然后,onerror事件设置到模块的errorHandler,作为以往任何请求的失实捕捉处理程序。最终,回调被实践来告诉调用者,数据库已经开垦并且正确地铺排,能够行使了。

下2个要贯彻的函数是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名字的数组。那几个函数这一次被布置为只行使3个object
store,不过即使您要求在事情中操作三个object store,你须求传递八个object
store的名字到数组中。事务函数的第2个参数是3个方式。

若果事情请求可用,您就可以透过传递须要的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节的代码在清单1所示。getAll函数首先张开数据库和做客object
store,它为store和cursor(游标)分别设置值。为数据库游标设置游标变量允许迭代object
store中的数据。data变量设置为一个空数组,充当数据的器皿,它回到给调用代码。

在store访问数据时,游标遍历数据库中的每条记下,会触发onsuccess事件处理程序。当每条记下走访时,store的数目能够透过e.target.result事件参数获得。尽管事实上多少从target.result的value属性中赢得,首先需求在打算访问value属性前确定保障result是3个有效的值。固然result存在,您能够增添result的值到数据数组,然后在result对象上调用continue函数来一连迭代object
store。最终,就算未有reuslt了,对store数据的迭代甘休,同时数据传递到回调,回调被实施。

近来模块能够从data
store获得全体数据,下2个内需贯彻的函数是承担访问单个记录。

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参数的值调换为三个整数。取决于函数被调用时,字符串或整数都只怕传递给函数。这几个完成跳过了对假若所给的字符串不能够转变到整数该怎么做的气象的处理。一旦2个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和3个回调函数。为了保障这么些完结简单,delete函数约定id的值为整数。您能够选拔创设三个越来越硬朗的兑现来处理id值无法分析成整数的失实例子的回调,但为了指引原因,代码示例是有意的。

比方id值能担保转变到贰个整数,数据库被张开,2个可写的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的二个可写实例。1旦store可用,二个新的请求通过调用clear函数来创立。壹旦clear操作成功,回调函数被实行。

 

执行用户分界面特定代码

前天全数特定于数据库的代码被封装在app.db模块中,用户分界面特定代码能够接纳此模块来与数据库交互。用户分界面特定代码的全体清单(index.ui.js)能够在清单3中赢得,完整的(index.html)页面包车型地铁HTML源代码能够在清单肆中收获。

怎么是 IndexedDB?

结论

趁着应用程序的需要的增加,你会发未来客户端高效存款和储蓄大批量的数据的优势。IndexedDB是足以在浏览器中一向动用且协助异步事务的文书档案数据库实现。即便浏览器的支撑也许否有限协理,但在适用的动静下,集成IndexedDB的Web应用程序具有强大的客户端数据的拜访技术。

在大多处境下,全数针对IndexedDB编写的代码是天赋基于请求和异步的。官方正规有同步API,可是那种IndexedDB只适合web
worker的前后文中使用。那篇小说公布时,还未有浏览器实现的同步格式的IndexedDB
API。

毫无疑问要确认保障代码在其余函数域外对商家特定的indexedDB, IDBTransaction, and
IDBKeyRange实例进行了规范化且使用了凶恶情势。那允许你防止浏览器错误,当在strict
mode下解析脚本时,它不会允许你对这几个对象重新赋值。

您无法不确认保证只传递正整数的版本号给数据库。传递到版本号的小数值会4舍伍入。由此,如若您的数据库方今版本一,您打算访问一.2版本,upgrade-needed事件不会触发,因为版本号最后评估是平等的。

当下施行函数表达式(IIFE)有时叫做分裂的名字。有时能够看来如此的代码组织措施,它叫做self-executing
anonymous functions(自进行匿名函数)或self-invoked anonymous
functions(自调用匿名函数)。为越发分解那些名称相关的来意和含义,请阅读Ben
Alman的作品Immediately Invoked Function Expression (IIFE) 。

Listing 1: Implementing the getAll function

JavaScript

getAll: function (callback) { db.open(function () { var store =
db.getObjectStore(), cursor = store.openCursor(), data = [];
cursor.onsuccess = function (e) { var result = e.target.result; if
(result && result !== null) { data.push(result.value);
result.continue(); } else { callback(data); } }; }); },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
getAll: function (callback) {
 
    db.open(function () {
 
        var
            store = db.getObjectStore(),
            cursor = store.openCursor(),
            data = [];
 
        cursor.onsuccess = function (e) {
 
            var result = e.target.result;
 
            if (result &&
                result !== null) {
 
                data.push(result.value);
                result.continue();
 
            } else {
 
                callback(data);
            }
        };
 
    });
},

Listing 2: Full source for database-specific code
(index.db.js)

JavaScript

// index.db.js ; window.indexedDB = window.indexedDB ||
window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange ||
window.msIDBKeyRange; (function(window){ ‘use strict’; var db = {
version: 1, // important: only use whole numbers! objectStoreName:
‘tasks’, instance: {}, upgrade: function (e) { var _db =
e.target.result, names = _db.objectStoreNames, name =
db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore(
name, { keyPath: ‘id’, autoIncrement: true }); } }, errorHandler:
function (error) { window.alert(‘error: ‘ + error.target.code);
debugger; }, open: function (callback) { var request =
window.indexedDB.open( db.objectStoreName, db.version); request.onerror
= db.errorHandler; request.onupgradeneeded = db.upgrade;
request.onsuccess = function (e) { db.instance = request.result;
db.instance.onerror = db.errorHandler; callback(); }; }, getObjectStore:
function (mode) { var txn, store; mode = mode || ‘readonly’; txn =
db.instance.transaction( [db.objectStoreName], mode); store =
txn.objectStore( db.objectStoreName); return store; }, save: function
(data, callback) { db.open(function () { var store, request, mode =
‘readwrite’; store = db.getObjectStore(mode), request = data.id ?
store.put(data) : store.add(data); request.onsuccess = callback; }); },
getAll: function (callback) { db.open(function () { var store =
db.getObjectStore(), cursor = store.openCursor(), data = [];
cursor.onsuccess = function (e) { var result = e.target.result; if
(result && result !== null) { data.push(result.value);
result.continue(); } else { callback(data); } }; }); }, get: function
(id, callback) { id = parseInt(id); db.open(function () { var store =
db.getObjectStore(), request = store.get(id); request.onsuccess =
function (e){ callback(e.target.result); }; }); }, ‘delete’: function
(id, callback) { id = parseInt(id); db.open(function () { var mode =
‘readwrite’, store, request; store = db.getObjectStore(mode); request =
store.delete(id); request.onsuccess = callback; }); }, deleteAll:
function (callback) { db.open(function () { var mode, store, request;
mode = ‘readwrite’; store = db.getObjectStore(mode); request =
store.clear(); request.onsuccess = callback; }); } }; window.app =
window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// index.db.js
 
;
 
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
 
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
 
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;
 
(function(window){
 
    ‘use strict’;
 
    var db = {
 
        version: 1, // important: only use whole numbers!
 
        objectStoreName: ‘tasks’,
 
        instance: {},
 
        upgrade: function (e) {
 
            var
                _db = e.target.result,
                names = _db.objectStoreNames,
                name = db.objectStoreName;
 
            if (!names.contains(name)) {
 
                _db.createObjectStore(
                    name,
                    {
                        keyPath: ‘id’,
                        autoIncrement: true
                    });
            }
        },
 
        errorHandler: function (error) {
            window.alert(‘error: ‘ + error.target.code);
            debugger;
        },
 
        open: function (callback) {
 
            var request = window.indexedDB.open(
                db.objectStoreName, db.version);
 
            request.onerror = db.errorHandler;
 
            request.onupgradeneeded = db.upgrade;
 
            request.onsuccess = function (e) {
 
                db.instance = request.result;
 
                db.instance.onerror =
                    db.errorHandler;
 
                callback();
            };
        },
 
        getObjectStore: function (mode) {
 
            var txn, store;
 
            mode = mode || ‘readonly’;
 
            txn = db.instance.transaction(
                [db.objectStoreName], mode);
 
            store = txn.objectStore(
                db.objectStoreName);
 
            return store;
        },
 
        save: function (data, callback) {
 
            db.open(function () {
 
                var store, request,
                    mode = ‘readwrite’;
 
                store = db.getObjectStore(mode),
 
                request = data.id ?
                    store.put(data) :
                    store.add(data);
 
                request.onsuccess = callback;
            });
        },
 
        getAll: function (callback) {
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];
 
                cursor.onsuccess = function (e) {
 
                    var result = e.target.result;
 
                    if (result &&
                        result !== null) {
 
                        data.push(result.value);
                        result.continue();
 
                    } else {
 
                        callback(data);
                    }
                };
 
            });
        },
 
        get: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    request = store.get(id);
 
                request.onsuccess = function (e){
                    callback(e.target.result);
                };
            });
        },
 
        ‘delete’: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    mode = ‘readwrite’,
                    store, request;
 
                store = db.getObjectStore(mode);
 
                request = store.delete(id);
 
                request.onsuccess = callback;
            });
        },
 
        deleteAll: function (callback) {
 
            db.open(function () {
 
                var mode, store, request;
 
                mode = ‘readwrite’;
                store = db.getObjectStore(mode);
                request = store.clear();
 
                request.onsuccess = callback;
            });
 
        }
    };
 
    window.app = window.app || {};
    window.app.db = db;
 
}(window));

Listing 3: Full source for user interface-specific code
(index.ui.js)

JavaScript

// index.ui.js ; (function ($, Modernizr, app) { ‘use strict’;
$(function(){ if(!Modernizr.indexeddb){
$(‘#unsupported-message’).show(); $(‘#ui-container’).hide(); return; }
var $deleteAllBtn = $(‘#delete-all-btn’), $titleText =
$(‘#title-text’), $notesText = $(‘#notes-text’), $idHidden =
$(‘#id-hidden’), $clearButton = $(‘#clear-button’), $saveButton =
$(‘#save-button’), $listContainer = $(‘#list-container’),
$noteTemplate = $(‘#note-template’), $emptyNote = $(‘#empty-note’);
var addNoTasksMessage = function(){ $listContainer.append(
$emptyNote.html()); }; var bindData = function (data) {
$listContainer.html(”); if(data.length === 0){ addNoTasksMessage();
return; } data.forEach(function (note) { var m = $noteTemplate.html(); m
= m.replace(/{ID}/g, note.id); m = m.replace(/{TITLE}/g, note.title);
$listContainer.append(m); }); }; var clearUI = function(){
$titleText.val(”).focus(); $notesText.val(”); $idHidden.val(”); }; //
select individual item $listContainer.on(‘click’, ‘a[data-id]’,
function (e) { var id, current; e.preventDefault(); current =
e.currentTarget; id = $(current).attr(‘data-id’); app.db.get(id,
function (note) { $titleText.val(note.title); $notesText.val(note.text);
$idHidden.val(note.id); }); return false; }); // delete item
$listContainer.on(‘click’, ‘i[data-id]’, function (e) { var id,
current; e.preventDefault(); current = e.currentTarget; id =
$(current).attr(‘data-id’); app.db.delete(id, function(){
app.db.getAll(bindData); clearUI(); }); return false; });
$clearButton.click(function(e){ e.preventDefault(); clearUI(); return
false; }); $saveButton.click(function (e) { var title =
$titleText.val(); if (title.length === 0) { return; } var note = {
title: title, text: $notesText.val() }; var id = $idHidden.val(); if(id
!== ”){ note.id = parseInt(id); } app.db.save(note, function(){
app.db.getAll(bindData); clearUI(); }); }); $deleteAllBtn.click(function
(e) { e.preventDefault(); app.db.deleteAll(function () {
$listContainer.html(”); addNoTasksMessage(); clearUI(); }); return
false; }); app.db.errorHandler = function (e) { window.alert(‘error: ‘ +
e.target.code); debugger; }; app.db.getAll(bindData); }); }(jQuery,
Modernizr, window.app));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// index.ui.js
 
;
 
(function ($, Modernizr, app) {
 
    ‘use strict’;
 
    $(function(){
 
        if(!Modernizr.indexeddb){
            $(‘#unsupported-message’).show();
            $(‘#ui-container’).hide();
            return;
        }
 
        var
          $deleteAllBtn = $(‘#delete-all-btn’),
          $titleText = $(‘#title-text’),
          $notesText = $(‘#notes-text’),
          $idHidden = $(‘#id-hidden’),
          $clearButton = $(‘#clear-button’),
          $saveButton = $(‘#save-button’),
          $listContainer = $(‘#list-container’),
          $noteTemplate = $(‘#note-template’),
          $emptyNote = $(‘#empty-note’);
 
        var addNoTasksMessage = function(){
            $listContainer.append(
                $emptyNote.html());
        };
 
        var bindData = function (data) {
 
            $listContainer.html(”);
 
            if(data.length === 0){
                addNoTasksMessage();
                return;
            }
 
            data.forEach(function (note) {
              var m = $noteTemplate.html();
              m = m.replace(/{ID}/g, note.id);
              m = m.replace(/{TITLE}/g, note.title);
              $listContainer.append(m);
            });
        };
 
        var clearUI = function(){
            $titleText.val(”).focus();
            $notesText.val(”);
            $idHidden.val(”);
        };
 
        // select individual item
        $listContainer.on(‘click’, ‘a[data-id]’,
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr(‘data-id’);
 
                app.db.get(id, function (note) {
                    $titleText.val(note.title);
                    $notesText.val(note.text);
                    $idHidden.val(note.id);
                });
 
                return false;
            });
 
        // delete item
        $listContainer.on(‘click’, ‘i[data-id]’,
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr(‘data-id’);
 
                app.db.delete(id, function(){
                    app.db.getAll(bindData);
                    clearUI();
                });
 
                return false;
        });
 
        $clearButton.click(function(e){
            e.preventDefault();
            clearUI();
            return false;
        });
 
        $saveButton.click(function (e) {
 
            var title = $titleText.val();
 
            if (title.length === 0) {
                return;
            }
 
            var note = {
                title: title,
                text: $notesText.val()
            };
 
            var id = $idHidden.val();
 
            if(id !== ”){
                note.id = parseInt(id);
            }
 
            app.db.save(note, function(){
                app.db.getAll(bindData);
                clearUI();
            });
        });
 
        $deleteAllBtn.click(function (e) {
 
            e.preventDefault();
 
            app.db.deleteAll(function () {
                $listContainer.html(”);
                addNoTasksMessage();
                clearUI();
            });
 
            return false;
        });
 
        app.db.errorHandler = function (e) {
            window.alert(‘error: ‘ + e.target.code);
            debugger;
        };
 
        app.db.getAll(bindData);
 
    });
 
}(jQuery, Modernizr, window.app));

Listing 3: Full HTML source (index.html)

JavaScript

<!doctype html> <html lang=”en-US”> <head> <meta
charset=”utf-8″> <meta http-equiv=”X-UA-Compatible”
content=”IE=edge”> <title>Introduction to
IndexedDB</title> <meta name=”description”
content=”Introduction to IndexedDB”> <meta name=”viewport”
content=”width=device-width, initial-scale=1″> <link
rel=”stylesheet”
href=”//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css”>
<link rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff” > <style>
h1 { text-align: center; color:#999; } ul li { font-size: 1.35em;
margin-top: 1em; margin-bottom: 1em; } ul li.small { font-style: italic;
} footer { margin-top: 25px; border-top: 1px solid #eee; padding-top:
25px; } i[data-id] { cursor: pointer; color: #eee; }
i[data-id]:hover { color: #c75a6d; } .push-down { margin-top: 25px; }
#save-button { margin-left: 10px; } </style> <script
src=”//cdnjs.cloudflare.com/ajax/libs/modernizr%20/2.8.2/modernizr.min.js”
></script> </head> <body class=”container”>
<h1>Tasks</h1> <div id=”unsupported-message” class=”alert
alert-warning” style=”display:none;”> <b>Aww snap!</b>
Your browser does not support indexedDB. </div> <div
id=”ui-container” class=”row”> <div class=”col-sm-3″> <a
href=”#” id=”delete-all-btn” class=”btn-xs”> <i class=”fa
fa-trash-o”></i> Delete All</a> <hr/> <ul
id=”list-container” class=”list-unstyled”></ul> </div>
<div class=”col-sm-8 push-down”> <input type=”hidden”
id=”id-hidden” /> <input id=”title-text” type=”text”
class=”form-control” tabindex=”1″ placeholder=”title” autofocus
/><br /> <textarea id=”notes-text” class=”form-control”
tabindex=”2″ placeholder=”text”></textarea> <div
class=”pull-right push-down”> <a href=”#” id=”clear-button”
tabindex=”4″>Clear</a> <button id=”save-button” tabindex=”3″
class=”btn btn-default btn-primary”> <i class=”fa
fa-save”></i> Save</button> </div> </div>
</div> <footer class=”small text-muted text-center”>by <a
href=”” target=”_blank”>Craig
Shoemaker</a> <a href=””
target=”_blank”> <i class=”fa fa-twitter”></i></a>
</footer> <script id=”note-template” type=”text/template”>
<li> <i data-id=”{ID}” class=”fa fa-minus-circle”></i>
<a href=”#” data-id=”{ID}”>{TITLE}</a> </li>
</script> <script id=”empty-note” type=”text/template”>
<li class=”text-muted small”>No tasks</li> </script>
<script src=”//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js”></script> <script
src=”index.db.js” type=”text/javascript”></script> <script
src=”index.ui.js” type=”text/javascript”></script>
</body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!doctype html>
<html lang="en-US">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Introduction to IndexedDB</title>
        <meta name="description"
              content="Introduction to IndexedDB">
        <meta name="viewport"
              content="width=device-width, initial-scale=1">
        <link rel="stylesheet"
              href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff" >
        <style>
            h1 {
                text-align: center;
                color:#999;
            }
 
            ul li {
                font-size: 1.35em;
                margin-top: 1em;
                margin-bottom: 1em;
            }
 
            ul li.small {
                font-style: italic;
            }
 
            footer {
                margin-top: 25px;
                border-top: 1px solid #eee;
                padding-top: 25px;
            }
 
            i[data-id] {
                cursor: pointer;
                color: #eee;
            }
 
            i[data-id]:hover {
                color: #c75a6d;
            }
 
            .push-down {
                margin-top: 25px;
            }
 
            #save-button {
                margin-left: 10px;
            }
        </style>
        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr
/2.8.2/modernizr.min.js" ></script>
    </head>
    <body class="container">
        <h1>Tasks</h1>
        <div id="unsupported-message"
             class="alert alert-warning"
             style="display:none;">
            <b>Aww snap!</b> Your browser does not support indexedDB.
        </div>
        <div id="ui-container" class="row">
            <div class="col-sm-3">
 
                <a href="#" id="delete-all-btn" class="btn-xs">
                    <i class="fa fa-trash-o"></i> Delete All</a>
 
                <hr/>
 
                <ul id="list-container" class="list-unstyled"></ul>
 
            </div>
            <div class="col-sm-8 push-down">
 
                <input type="hidden" id="id-hidden" />
 
                <input
                       id="title-text"
                       type="text"
                       class="form-control"
                       tabindex="1"
                       placeholder="title"
                       autofocus /><br />
 
                <textarea
                          id="notes-text"
                          class="form-control"
                          tabindex="2"
                          placeholder="text"></textarea>
 
                <div class="pull-right push-down">
 
                    <a href="#" id="clear-button" tabindex="4">Clear</a>
 
                    <button id="save-button"
                            tabindex="3"
                            class="btn btn-default btn-primary">
                                <i class="fa fa-save"></i> Save</button>
                </div>
            </div>
        </div>
        <footer class="small text-muted text-center">by
            <a href="http://craigshoemaker.net" target="_blank">Craig Shoemaker</a>
            <a href="http://twitter.com/craigshoemaker" target="_blank">
                <i class="fa fa-twitter"></i></a>
        </footer>
        <script id="note-template" type="text/template">
            <li>
                <i data-id="{ID}" class="fa fa-minus-circle"></i>
                <a href="#" data-id="{ID}">{TITLE}</a>
            </li>
        </script>
        <script id="empty-note" type="text/template">
            <li class="text-muted small">No tasks</li>
        </script>
        <script src="//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js"></script>
        <script src="index.db.js" type="text/javascript"></script>
        <script src="index.ui.js" type="text/javascript"></script>
    </body>
</html>

赞 1 收藏
评论

在 20拾 年 2月 18 日,W3C宣布弃用Web
SQL数据库规范。那也正是提出网络开采人士不要再使用那种手艺了,该标准也不会再得到新的翻新,而且不鼓励浏览器供应商辅助该手艺。

至于笔者:cucr

图片 9

今日头条天涯论坛:@hop_ping
个人主页 ·
小编的篇章 ·
17

图片 10

 

代替的是
IndexedDB,本学科的大旨是开拓职员应选取那种多少存款和储蓄在客户端上囤积数据并张开操作。

 

各大主流浏览器(包罗Chrome浏览器、Safari、Opera等)和大致全体基于Webkit的移动装备均支持WebSQL,并且很有相当大希望在可预言的前途三番五次提供支撑。

 

先决条件

该示例使用命名空间封装数据库逻辑。 

 

[html] 

var html5rocks = {};  html5rocks.indexedDB = {};  var html5rocks = {};

html伍rocks.indexedDB = {};异步和事务性

在大大多意况下,假使您使用的是索引型数据库,那么就会动用异步API。异步API是非阻塞系统,因此不会经过重返值得到数量,而是得到传递到钦命回调函数的数据。

 

透过 HTML
援救IndexedDB是事务性的。在事情之外是相当小概执行命令或张开指针的。事务包罗如下类型:读/写作业、只读事务和快照事务。在本教程中,大家使用的是读/写作业。

 

第 一步:张开数据库

你必须先展开数据库,工夫对其打开操作。 

 

[html]

html5rocks.indexedDB.db = null;    html5rocks.indexedDB.open =
function() {    var request = indexedDB.open(“todos”);    
 request.onsuccess = function(e) {      html5rocks.indexedDB.db =
e.target.result;      // Do some more stuff in a minute    };    
 request.onfailure = html5rocks.indexedDB.onerror;  };
 html5rocks.indexedDB.db = null;

 

html5rocks.indexedDB.open = function() {

  var request = indexedDB.open(“todos”);

 

  request.onsuccess = function(e) {

    html5rocks.indexedDB.db = e.target.result;

    // Do some more stuff in a minute

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

};大家已开荒名称为“todos”的数据库,并已将其分配给html5rocks.indexedDB对象中的db变量。现在大家能够在整整课程中应用此变量来引用大家的数据库。

 

第 贰步:创立对象存款和储蓄

您不得不在“SetVersion”事务内创造对象存款和储蓄。笔者还未有介绍setVersion,那是八个不胜首要的主意,那是代码中唯1能够供你创制对象存款和储蓄和目录的地点。

 

[html]

html5rocks.indexedDB.open = function() {    var request =
indexedDB.open(“todos”,      “This is a description of the database.”);
     request.onsuccess = function(e) {      var v = “1.0”;    
 html5rocks.indexedDB.db = e.target.result;      var db =
html5rocks.indexedDB.db;      // We can only create Object stores in a
setVersion transaction;      if(v!= db.version) {        var setVrequest
= db.setVersion(v);          // onsuccess is the only place we can
create Object Stores        setVrequest.onfailure =
html5rocks.indexedDB.onerror;        setVrequest.onsuccess = function(e)
{          var store = db.createObjectStore(“todo”,            {keyPath:
“timeStamp”});            html5rocks.indexedDB.getAllTodoItems();      
 };      }        html5rocks.indexedDB.getAllTodoItems();    };    
 request.onfailure = html5rocks.indexedDB.onerror;  }
 html5rocks.indexedDB.open = function() {

  var request = indexedDB.open(“todos”,

    “This is a description of the database.”);

 

  request.onsuccess = function(e) {

    var v = “1.0”;

    html5rocks.indexedDB.db = e.target.result;

    var db = html5rocks.indexedDB.db;

    // We can only create Object stores in a setVersion transaction;

    if(v!= db.version) {

      var setVrequest = db.setVersion(v);

 

      // onsuccess is the only place we can create Object Stores

      setVrequest.onfailure = html5rocks.indexedDB.onerror;

      setVrequest.onsuccess = function(e) {

发表评论

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

网站地图xml地图