您的位置:永利集团登录网址 > web资讯 > 深入解析HTML5中的IndexedDB索引数据库,html5indexe

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

2019-10-03 14:07

前面贰个的数据库: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

那篇小说主要介绍了尖锐剖判HTML第55中学的IndexedDB索引数据库,富含事务锁等基本作用的相干应用示例,须要的意中人能够参照下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5 WEB应用在顾客浏览器端存款和储蓄数据。对于使用来讲IndexedDB特别有力、有用,能够在顾客端的chrome,IE,Firefox等WEB浏览器中积存多量数量,上面简介一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的数额存款和储蓄,能够在客商端存款和储蓄、操作数据,能够使利用加载地越来越快,更加好地响应。它区别于关系型数据库,具备数据表、记录。它影响着大家安顿和开创应用程序的主意。IndexedDB 创建有数据类型和省略的JavaScript持久对象的object,各类object能够有目录,使其立竿见影地查询和遍历整个群集。本文为您提供了什么在Web应用程序中使用IndexedDB的真人真事事例。
 
开始 大家要求在实践前包括下日前置代码

JavaScript Code复制内容到剪贴板

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

 
打开IndexedDB 在开立数据库在此之前,大家第一须要为数据库创设数量,借使大家有如下的客商音讯:

JavaScript Code复制内容到剪贴板

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

如今我们须要用open()方法打开我们的数据库:

JavaScript Code复制内容到剪贴板

  1. var db;   
  2. var request = indexedDB.open("databaseName", 1);   
  3.     
  4. request.onerror = function(e) {   
  5. console.log("error: ", e);   
  6. };   
  7.     
  8. request.onsuccess = function(e) {   
  9. db = request.result;   
  10. console.log("success: "+ db);   
  11. };   
  12. request.onupgradeneeded = function(e) {   
  13.     
  14. }  

如上所示,我们早已开垦了名字为"databaseName",钦命版本号的数据库,open()方法有八个参数:
1.先是个参数是数据库名称,它会检查评定名叫"databaseName"的数据库是不是已经存在,即使存在则张开它,不然创制新的数据库。
2.次之个参数是数据库的版本,用于客商更新数据库结构。
 
onSuccess处理 产生成功事件时“onSuccess”被触发,倘若全数成功的央浼都在此管理,我们能够透过赋值给db变量保存央求的结果供之后选用。
 
onerror的管理程序 发生错误事件时“onerror”被触发,假设展开数据库的进程中战败。
 
Onupgradeneeded管理程序 如果您想翻新数据库(创造,删除或涂改数据库),那么你必需贯彻onupgradeneeded管理程序,使您能够在数据库中做别的更动。 在“onupgradeneeded”管理程序中是能够改变数据库的布局的举世无双地点。
 
制造和增加数据到表:
IndexedDB使用对象存储来囤积数据,实际不是由此表。 每当一个值存款和储蓄在对象存款和储蓄中,它与贰个键相关联。 它同意大家创制的另外对象存款和储蓄索引。 索引允许大家访问存款和储蓄在目的存款和储蓄中的值。 上面包车型地铁代码呈现了何等成立对象存款和储蓄并插入预先希图好的数额:

JavaScript Code复制内容到剪贴板

  1. request.onupgradeneeded = function(event) {   
  2. var objectStore = event.target.result.createObjectStore("users", {keyPath: "id"});   
  3. for (var i in userData) {   
  4. objectStore.add(userData[i]);    
  5. }   
  6. }  

作者们使用createObjectStore()方法创设叁个指标存储。 此方法接受五个参数:

  • 积攒的名目和参数对象。 在此地,我们有二个名称叫"users"的对象存款和储蓄,并定义了keyPath,那是指标独一性的品质。 在此处,大家采用“id”作为keyPath,这么些值在指标存款和储蓄中是独一的,大家不可能不保障该“ID”的天性在指标存款和储蓄中的每种对象中设有。 一旦创造了对象存储,大家得以起头选用for循环增加数据进去。
     
    手动将数据增加到表:
    咱俩得以手动增添额外的数码到数据库中。

JavaScript Code复制内容到剪贴板

  1. function Add() {   
  2. var request = db.transaction(["users"], "readwrite").objectStore("users")   
  3. .add({ id: "3", name: "Gautam", age: 30, email: "[email protected]" });   
  4.     
  5. request.onsuccess = function(e) {   
  6. alert("Gautam has been added to the database.");   
  7. };   
  8.     
  9. request.onerror = function(e) {   
  10. alert("Unable to add the information.");    
  11. }   
  12.     
  13. }  

前边大家在数据库中做其余的CRUD操作(读,写,修改),必须使用专门的学业。 该transaction()方法是用来内定大家想要进行事务管理的靶子存款和储蓄。 transaction()方法接受3个参数(第三个和第八个是可选的)。 第一个是大家要管理的靶子存款和储蓄的列表,第一个钦定大家是或不是要只读/读写,第三个是本子变化。
 
从表中读取数据 get()方法用于从目的存款和储蓄中找找数据。 大家前边已经设置对象的id作为的keyPath,所以get()方法将寻觅具备一样id值的靶子。 下边包车型客车代码将回来大家命名称为“Bidulata”的对象:

JavaScript Code复制内容到剪贴板

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

 
从表中读取全部数据
上边包车型地铁法门搜索表中的全体数据。 这里大家利用游标来搜索对象存款和储蓄中的全体数据:

JavaScript Code复制内容到剪贴板

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

该openCursor()用于遍历数据库中的三个记录。 在continue()函数中一连读取下一条记下。
删除表中的记录 上面包车型大巴措施从指标中去除记录。

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

localStorage是不带lock功用的。那么要落到实处前端的数目分享而且供给lock功效那就需求利用其余本积存方式,比如indexedDB。indededDB使用的是事务管理的建制,这实在正是lock作用。
  做这一个测量检验必要先轻便的卷入下indexedDB的操作,因为indexedDB的一连比较麻烦,並且八个测量检验页面都亟待用到

JavaScript Code复制内容到剪贴板

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

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

永利游戏平台 2

测量试验的时候b.html中恐怕不会及时有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了事情丢队列中等待。但是无论怎样,输出结果也不会是1以此值。因为indexedDB的微小管理单位是职业,并非localStorage那样以表明式为单位。这样一旦把lock和unlock之间要求管理的事物归入三个事务中就能够兑现。别的,浏览器对indexedDB的协理不及localStorage,所以使用时还得思考浏览器宽容。

那篇小说主要介绍了入木四分剖判HTML5中的IndexedDB索引数据库,包含事务锁等基本成效的相干使...

简介

统一筹划指南

IndexedDB的架构很像在部分盛行的服务器端NOSQL数据库达成中的设计标准类型。面向对象数据通过object stores(对象仓库)实行悠久化,全数操作基于须要同期在作业限制内实施。事件生命周期令你能够决定数据库的铺排,错误通过荒谬冒泡来使用API处理。

IndexedDB是HTML5中的新添效果与利益。互联网数据库托管并留存在客商的浏览器内。只要让开采职员通过丰裕的查询效率创造应用,就足以预知到,将会产出能够同期在线和离线使用的新型互联网接纳。

目的仓库

object store是IndexedDB数据库的基本功。假如您使用过关周到据库,日常能够将object store等价于一个多少库表。Object stores包括三个或五个目录,在store中坚守一对键/值操作,那提供一种高效牢固数据的不二诀要。

当你安顿一个object store,你不能不为store接纳三个键。键在store中可以以“in-line”或“out-of-line”的措施存在。in-line键通过在多少对象上引用path来维持它在object store的独一性。为了注脚这一点,想想三个总结电子邮件地址属性Person对象。您能够配备你的store使用in-line键emailAddress,它能担保store(长久化对象中的数据)的独一性。其他,out-of-line键通过单独于数据的值识别唯一性。在这种情形下,你能够把out-of-line键比作一个寸头值,它(整数值)在关全面据库中担负记录的主键。

图1展现了职分数据保存在职责的object store,它利用in-line键。在这些案例中,键对应于对象的ID值。

 

依靠事务

不一致于一些价值观的关周详据库的贯彻,每一个对数据库操作是在叁个事务的内外文中试行的。事务限制一遍影响叁个或多少个object stores,你通过传播一个object store名字的数组到创建筑工程作限制的函数来定义。

创设职业的第叁个参数是工作格局。当呼吁一个事务时,必得调整是依照只读照旧读写形式央浼访问。事务是能源密集型的,所以只要您无需改动data store中的数据,你只须求以只读情势对object stores集结实行呼吁访问。

清单2示范了什么行使特别的格局创立三个事务,并在那片小说的 Implementing Database-Specific Code 部分实行了详尽座谈。

IndexedDB是什么?

基于央求

乃至于这里,有八个反复出现的主题,您恐怕曾经注意到。对数据库的每一次操作,描述为通过三个伸手展开数据库,访谈多个object store,再持续。IndexedDB API天生是依照哀告的,那也是API异步特性提醒。对于你在数据库实施的历次操作,你必得首先为这么些操作创制三个伸手。当呼吁完毕,你能够响应由哀告结果爆发的风浪和不当。

本文完结的代码,演示了什么样运用要求打开数据库,创设二个事情,读取object store的剧情,写入object store,清空object store。

IndexedDB是指标存储,它区别于带有表格(包涵行和列的晤面)的关周到据库。那是三个入眼的一直分化,何况会潜濡默化您设计和构建利用的主意。

打开数据库的呼吁生命周期

IndexedDB使用事件生命周期管理数据库的开垦和布署操作。图2示范了叁个开垦的呼吁在自然的条件下发出upgrade need事件。

永利游戏平台 3

图2:IndexedDB展开供给的生命周期

不无与数据库的彼此最初于二个开垦的呼吁。试图张开数据库时,您必需传递七个被呼吁数据库的版本号的整数值。在开发恳求时,浏览器相比较你传入的用来打开诉求的版本号与实际数据库的版本号。假诺所央求的版本号高于浏览器中当前的版本号(大概今后尚无存在的数据库),upgrade needed事件触发。在uprade need事件之间,你有机遇通过增添或移除stores,键和索引来操纵object stores。

若果所央浼的数据库版本号和浏览器的此时此刻版本号一致,大概晋级进度完毕,二个开荒的数据库将回来给调用者。

 

谬误冒泡

自然,不时候,央求可能不会按预想实现。IndexedDB API通过荒谬冒泡效果来提携追踪和保管不当。如若八个特定的伸手遭受错误,你能够品味在伸手对象上管理错误,或然你能够允许错误通过调用栈冒泡向上传递。这些冒泡性子,使得你无需为各种央求完毕特定错误管理操作,而是能够采用只在贰个越来越高档别上增添错误管理,它给你八个机缘,保持您的错误管理代码简洁。本文中落到实处的例证,是在一个高端别处理错误,以便更加细粒度操作产生的别样不当冒泡到通用的错误管理逻辑。

在守旧的关周密据存款和储蓄中,大家有贰个“待办事项”的表格,当中各行存款和储蓄了客户待办事项数据的集纳,而各列则是多少的命名类型。要插入数据,通常使用如下语义:INSERTINTO Todo(id, data, update_time) VALUES (1, "Test","01/01/2010");

浏览器支持

唯恐在付出Web应用程序最注重的标题是:“浏览器是不是协理自己想要做的?“尽管浏览器对IndexedDB的支撑在后续抓牢,选取率而不是我们所希望的那么普及。图3彰显了caniuse.com网址的报告,支持IndexedDB的为66%多一小点。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全帮助IndexedDB,Internet Explorer和三星部分协助。尽管那几个列表的维护者是安心乐意的,但它并未有告知全数故事。

永利游戏平台 4

图3:浏览器对IndexedDB的帮助,来自caniuse.com

除非可怜新本子的Safari和iOS Safari 辅助IndexedDB。据caniuse.com显示,那只占大致0.01%的芸芸众生浏览器选拔。IndexedDB不是多少个您以为能够理所必然得到帮忙的今世Web API,然则你将高速会如此以为。

 

另一种接纳

浏览器帮助本地数据库而不是从IndexedDB才起来兑现,它是在WebSQL贯彻之后的一种新办法。类似IndexedDB,WebSQL是一个客户端数据库,但它看成八个关周详据库的达成,使用结构化查询语言(SQL)与数据库通讯。WebSQL的野史充满了屈曲,但底线是不曾主流的浏览器厂家对WebSQL继续支持。

若是WebSQL实际上是二个撇下的技能,为何还要提它吗?有意思的是,WebSQL在浏览器里拿走加强的帮忙。Chrome, Safari, iOS Safari, and Android 浏览器都帮忙。别的,并非那么些浏览器的风行版本才提供协助,多数那个最新最棒的浏览器之前的本子也得以支撑。有意思的是,假设你为WebSQL增添辅助来支撑IndexedDB,你忽地意识,许多浏览器厂家和版本成为支持浏览器内置数据库的某种化身。

故此,如若您的应用程序真正必要二个顾客端数据库,你想要达到的最高档其他采取恐怕,当IndexedDB不可用时,大概你的应用程序可能看起来需求选用采用WebSQL来支撑客户端数据架构。就算文档数据库和关周密据库管理数占有引人注指标出入,但假诺您有不利的指雁为羹,就能够使用本地数据库创设贰个应用程序。

IndexedDB的不一样之处在于,您能够创造某些项目数据的目的存款和储蓄,然后只需将JavaScript对象留存在该存款和储蓄中就可以。每一个对象存款和储蓄都足以有目录的聚众,那样就会开展火速的查询和迭代。

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

现今最重大的标题:“IndexedDB是还是不是合乎本人的应用程序?“像过去一律,答案是迟早的:“视意况而定。“首先当您筹划在顾客端保存数据时,你会设想HTML5本土存款和储蓄。本地存款和储蓄获得大规模浏览器的支撑,有特别轻巧使用的API。轻松有其优势,但其劣点是无力回天支撑复杂的探究战术,存款和储蓄大量的多少,并提供职业辅助。

IndexedDB是一个数据库。所以,当您想为客户端做出决定,思考你哪些在服务端选择一个持久化介质的数据库。你大概会问本人有个别难点来支持调节顾客端数据库是不是切合你的应用程序,富含:

  • 你的客商通过浏览器访问您的应用程序,(浏览器)援助IndexedDB API吗 ?
  • 您需求仓库储存大批量的数目在客户端?
  • 你需求在二个特大型的多少集结中高速稳固单个数分公司?
  • 你的架构在顾客端须求职业帮助啊?

假诺你对里面包车型大巴别的难题答疑了“是的”,很有非常的大希望,IndexedDB是你的应用程序的一个很好的候选。

 

使用IndexedDB

当今,你早已有空子纯熟了有的的一体化概念,下一步是始于兑现基于IndexedDB的应用程序。第三个步骤须要统一IndexedDB在区别浏览器的贯彻。您可以很轻巧地加上各样商家性格的选项的自己研究,同一时候在window对象上把它们设置为官方对象同样的名号。上面包车型大巴清单展现了window.indexedDB,window.IDBTransaction,window.IDBKeyRange的终极结果是怎么都被更新,它们被装置为对应的浏览器的一定完毕。

JavaScript

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

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

现行反革命,每一种数据库相关的全局对象具备准确的本子,应用程序可以希图选择IndexedDB早先职业。

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

动用概述

在本教程中,您将学习怎么样创造二个运用IndexedDB存款和储蓄数据的模块化JavaScript应用程序。为了驾驭应用程序是咋做事的,参谋图4,它陈说了职分应用程序处于空白状态。从此处您可感觉列表增加新任务。图5展现了录入了多少个任务到系统的画面。图6来得怎么删除四个任务,图7彰显了正在编写制定职分时的应用程序。

永利游戏平台 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。

本课程只是举了八个实际上示例,告诉您针对编写为运用WebSQL 的依存应用怎样接纳IndexedDB。 

Implementing Database-Specific Code

对数据库的各类操作关联着贰个先决条件,即有五个展开的数据库。当数据库正在被张开时,通过检查数据库版本来剖断数据库是不是要求其他变动。上边包车型地铁代码突显了模块怎样追踪当前版本,object store名、某成员(保存了要是数据库展开央求完毕后的数据库当前实例)。

JavaScript

version: 1, objectStoreName: 'tasks', instance: {},

1
2
3
version: 1,
objectStoreName: 'tasks',
instance: {},

在那边,数据库张开央求发生时,模块央浼版本1数据库。假设数据库荒诞不经,也许版本小于1,upgrade needed事件在开拓央浼完毕前触发。那么些模块棉被服装置为只利用二个object store,所以名字直接定义在这里。最终,实例成员被成立,它用于保存一旦打开央浼完结后的数据库当前实例。

接下去的操作是贯彻upgrade needed事件的事件管理程序。在此间,检查当前object store的名字来判别央浼的object store名是不是存在,若是官样文章,创制object store。

JavaScript

upgrade: function (e) { var _db = e.target.result, names = _db.objectStoreNames, name = db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore( name, { keyPath: 'id', autoIncrement: true }); } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upgrade: function (e) {
    var
        _db = e.target.result,
        names = _db.objectStoreNames,
        name = db.objectStoreName;
    if (!names.contains(name)) {
        _db.createObjectStore(
            name,
            {
                keyPath: 'id',
                autoIncrement: true
            });
    }
},

在那么些事件管理程序里,通过事件参数e.target.result来访谈数据库。当前的object store名称的列表在_db.objectStoreName的字符串数组上。以后,如若object store不设有,它是经过传递object store名称和store的键的定义(自增,关联到数量的ID成员)来创建。

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

JavaScript

errorHandler: function (error) { window.alert('error: ' + error.target.code); debugger; },

1
2
3
4
errorHandler: function (error) {
    window.alert('error: ' + error.target.code);
    debugger;
},

在此处,errorHandler在三个警告框展现任何不当。这么些函数是故意保持轻松,对开荒和谐,当您读书应用IndexedDB,您能够很容易地看来任何错误(当他俩产生时)。当您妄想在生育条件使用那一个模块,您必要在那个函数中落实部分错误管理代码来和您的应用程序的上下文打交道。

近期基础完毕了,这一节的其他部分将演示怎么样贯彻对数据库实践一定操作。第1个要求检讨的函数是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的名字到数组中。事务函数的第2个参数是八个方式。

假如事情央浼可用,您就可以通过传递必要的object store名字来调用objectStore函数以获取object store实例的访谈权。这几个模块的别的函数使用getObjectStore来猎取object store的访谈权。

下二个贯彻的函数是save函数,推行插入或更新操作,它依照传入的多寡是不是有多少个ID值。

JavaScript

save: function (data, callback) { db.open(function () { var store, request, mode = 'readwrite'; store = db.getObjectStore(mode), request = data.id ? store.put(data) : store.add(data); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
12
save: function (data, callback) {
    db.open(function () {
        var store, request,
            mode = 'readwrite';
 
        store = db.getObjectStore(mode),
        request = data.id ?
            store.put(data) :
            store.add(data);
        request.onsuccess = callback;
    });
},

save函数的七个参数分别是索要保留的数据对象实例和操作成功后要求施行的回调。读写情势用于将数据写入数据库,它被盛传到getObjectStore来得到object store的三个可写实例。然后,检查数据对象的ID成员是不是存在。如果存在ID值,数据必得创新,put函数被调用,它成立持久化须要。不然,假诺ID官样文章,这是新数据,add必要重回。最终,不管put或许add 须求是或不是试行了,success事件管理程序须求安装在回调函数上,来报告调用脚本,一切进展顺遂。

下一节的代码在清单1所示。getAll函数首先张开数据库和拜望object store,它为store和cursor(游标)分别设置值。为数据库游标设置游标变量允许迭代object store中的数据。data变量设置为叁个空数组,当做数据的器皿,它回到给调用代码。

在store访谈数据时,游标遍历数据库中的每条记下,会触发onsuccess事件管理程序。当每条记下拜会时,store的数量能够透过e.target.result事件参数得到。就算实际数目从target.result的value属性中获得,首先须求在试图访问value属性前确认保障result是一个可行的值。尽管result存在,您能够增添result的值到数据数组,然后在result对象上调用continue函数来延续迭代object store。最终,若无reuslt了,对store数据的迭代截止,同期数据传递到回调,回调被施行。

近年来模块能够从data store得到全体数据,下一个亟需完结的函数是担任访谈单个记录。

JavaScript

get: function (id, callback) { id = parseInt(id); db.open(function () { var store = db.getObjectStore(), request = store.get(id); request.onsuccess = function (e){ callback(e.target.result); }; }); },

1
2
3
4
5
6
7
8
9
10
11
get: function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            store = db.getObjectStore(),
            request = store.get(id);
        request.onsuccess = function (e){
            callback(e.target.result);
        };
    });
},

get函数施行的率先步操作是将id参数的值调换为一个偏分头。决议于函数被调用时,字符串或整数都也许传递给函数。那几个达成跳过了对假设所给的字符串不可能调换成整数该怎么做的事态的拍卖。一旦叁个id值妄图好了,数据库展开了和object store能够访谈了。获取访谈get央浼出现了。恳求成功时,通过传播e.target.result来施行回调。它(e.target.result)是经过调用get函数到手的单条记录。

目前封存和接纳操作已经面世了,该模块还亟需从object store移除数量。

JavaScript

'delete': function (id, callback) { id = parseInt(id); db.open(function () { var mode = 'readwrite', store, request; store = db.getObjectStore(mode); request = store.delete(id); request.onsuccess = callback; }); },

1
2
3
4
5
6
7
8
9
10
11
'delete': function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            mode = 'readwrite',
            store, request;
        store = db.getObjectStore(mode);
        request = store.delete(id);
        request.onsuccess = callback;
    });
},

delete函数的称号用单引号,因为delete是JavaScript的保留字。那能够由你来调控。您能够采纳命名函数为del或别的名目,不过delete用在这几个模块为了API尽大概好的发挥。

传递给delete函数的参数是指标的id和叁个回调函数。为了维持这一个完毕简单,delete函数约定id的值为整数。您能够选拔创制二个更加结实的落到实处来管理id值不可能剖判成整数的不当例子的回调,但为了辅导原因,代码示例是明知故犯的。

假使id值能确认保障调换来一个整数,数据库被张开,叁个可写的object store获得,delete函数字传送入id值被调用。当呼吁成功时,将举行回调函数。

在少数情况下,您恐怕须求删除二个object store的富有的记录。在这种境况下,您访谈store同有的时候候免去全体剧情。

JavaScript

deleteAll: function (callback) { db.open(function () { var mode, store, request; mode = 'readwrite'; store = db.getObjectStore(mode); request = store.clear(); request.onsuccess = callback; }); }

1
2
3
4
5
6
7
8
9
deleteAll: function (callback) {
    db.open(function () {
        var mode, store, request;
        mode = 'readwrite';
        store = db.getObjectStore(mode);
        request = store.clear();
        request.onsuccess = callback;
    });
}

这边deleteAll函数担负张开数据库和做客object store的三个可写实例。一旦store可用,三个新的哀告通过调用clear函数来创制。一旦clear操作成功,回调函数被实行。

 

推行顾客分界面特定代码

明天颇有特定于数据库的代码被封装在app.db模块中,客户分界面特定代码能够利用此模块来与数据库交互。用户分界面特定代码的欧洲经济共同体清单(index.ui.js)可以在清单3中拿走,完整的(index.html)页面包车型大巴HTML源代码能够在清单4中获得。

怎么是 IndexedDB?

结论

乘势应用程序的要求的提升,你会开采在顾客端高效存款和储蓄大量的数额的优势。IndexedDB是足以在浏览器中央直属机关接使用且帮助异步事务的文档数据库完结。固然浏览器的支撑或者还是不能够维系,但在适龄的状态下,集成IndexedDB的Web应用程序具有强有力的客商端数据的拜谒本事。

在多数状态下,全体针对IndexedDB编写的代码是天赋基于央求和异步的。官方正规有同步API,不过这种IndexedDB只切合web worker的左右文中使用。那篇小说公布时,还尚未浏览器达成的一只格式的IndexedDB API。

必然要确定保证代码在任何函数域外对商家特定的indexedDB, IDBTransaction, and IDBKeyRange实例进行了规范化且使用了凶暴模式。那允许你制止浏览器错误,当在strict mode下分析脚本时,它不会容许你对那多少个对象重新赋值。

你必需有限帮衬只传递正整数的版本号给数据库。传递到版本号的小数值会四舍五入。由此,要是你的数据库前段时间版本1,您准备访谈1.2本子,upgrade-needed事件不会接触,因为版本号最终评估是毫发不爽的。

当即实行函数表明式(IIFE)一时叫做差异的名字。有的时候可以看见那般的代码社团办公室法,它称为self-executing anonymous functions(自执行佚名函数)或self-invoked anonymous functions(自调用佚名函数)。为越来越解释这几个名称相关的意图和意义,请阅读Ben Alman的篇章Immediately Invoked Function Expression (IIFE) 。

Listing 1: Implementing the getAll function

JavaScript

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

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

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

JavaScript

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

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

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

JavaScript

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

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

Listing 3: Full HTML source (index.html)

JavaScript

<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Introduction to IndexedDB</title> <meta name="description" content="Introduction to IndexedDB"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/css/font-awesome.min.css" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/FontAwesome.otf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.eot" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.svg" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" > <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs /font-awesome/4.1.0/fonts/fontawesome-webfont.woff" > <style> h1 { text-align: center; color:#999; } ul li { font-size: 1.35em; margin-top: 1em; margin-bottom: 1em; } ul li.small { font-style: italic; } footer { margin-top: 25px; border-top: 1px solid #eee; padding-top: 25px; } i[data-id] { cursor: pointer; color: #eee; } i[data-id]:hover { color: #c75a6d; } .push-down { margin-top: 25px; } #save-button { margin-left: 10px; } </style> <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr /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 收藏 评论

在 二零零六 年 8月 18 日,W3C公布弃用Web SQL数据库规范。那也正是建议互联网开荒人士不要再采纳这种工夫了,该标准也不会再得到新的换代,何况不鼓劲浏览器经销商帮衬该技术。

有关小编:cucr

永利游戏平台 9

博客园网易:@hop_ping 个人主页 · 作者的作品 · 17

永利游戏平台 10

 

代替的是 IndexedDB,本课程的主题是开辟职员应使用这种多少存款和储蓄在顾客端上囤积数据并开展操作。

 

各大主流浏览器(包涵Chrome浏览器、Safari、Opera等)和大约具有基于Webkit的运动设备均帮助WebSQL,况且很有希望在可预知的未来继续提供援助。

 

先决条件

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

 

[html] 

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

html5rocks.indexedDB = {};异步和事务性

在大大多情景下,倘若您使用的是索引型数据库,那么就能够使用异步API。异步API是非阻塞系统,由此不会经过重回值获得多少,而是获得传递到钦命回调函数的数据。

 

透过 HTML 帮忙IndexedDB是事务性的。在事情之外是力所不比推行命令或打开指针的。事务满含如下类型:读/写作业、只读事务和快速照相事务。在本教程中,大家运用的是读/写作业。

 

第 1步:张开数据库

你必得先开荒数据库,工夫对其实行操作。 

 

[html]

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

 

html5rocks.indexedDB.open = function() {

  var request = indexedDB.open("todos");

 

  request.onsuccess = function(e) {

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

    // Do some more stuff in a minute

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

};我们已张开名称为“todos”的数据库,并已将其分配给html5rocks.indexedDB对象中的db变量。现在大家能够在方方面面课程中利用此变量来援用大家的数据库。

 

第 2步:创造对象存款和储蓄

您不得不在“SetVersion”事务内创制对象存储。笔者还不曾介绍setVersion,那是一个万分关键的措施,那是代码中不二法门能够供你创制对象存款和储蓄和目录的地点。

 

[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) {

        var store = db.createObjectStore("todo",

          {keyPath: "timeStamp"});

 

        html5rocks.indexedDB.getAllTodoItems();

      };

    }

 

    html5rocks.indexedDB.getAllTodoItems();

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

}上述代码其实有点不清意义。我们在 API中定义了“open”方法,调用此方式就能够张开“todos”数据库。展开供给不是随即推行的,而是再次回到IDBRequest。假设当前函数存在,则会调用indexedDB.open方法。那与大家见怪不怪钦定异步回调的主意略有差别,不过大家在回调实践前,有空子向IDBRequest对象附加大家和煦的监听器。

 

假如展开伏乞成功了,大家的 onsuccess回调就能够施行。在此回调中,大家应反省数据库版本,借使与预期版本不符,则调用“setVersion”。

 

setVersion 是代码中有一无二能让我们改换数据库结构的地点。在setVersion中,大家得以成立和删除对象存款和储蓄,以及营造和删除索引。调用setVersion可再次回到IDBRequest对象,供大家在里头附加回调。假设成功了,大家就起来创设对象存款和储蓄。

 

因而对 createObjectStore单次调用创制对象存款和储蓄。该方法会命名存款和储蓄以及参数对象。参数对象十二分首要,它可让您定义重要的可选属性。就我们来说,定义keyPath属性可让单个对象在蕴藏中兼有独一性。本例中的该属性为“timeStamp”。objectStore中积累的种种对象都无法不有“timeStamp”。

 

创设了目的存款和储蓄后,大家调用 getAllTodoItems方法。

 

第 3步:向指标存储添扩大少

小编们要创设的是待办事项列表管理器,由此一定要能够向数据库中加多待办事项。方法如下:

 

[html] 

html5rocks.indexedDB.addTodo = function(todoText) {    var db = html5rocks.indexedDB.db;    var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);    var store = trans.objectStore("todo");    var request = store.put({      "text": todoText,      "timeStamp" : new Date().getTime()    });      request.onsuccess = function(e) {      // Re-render all the todo's      html5rocks.indexedDB.getAllTodoItems();    };      request.onerror = function(e) {      console.log(e.value);    };  };  html5rocks.indexedDB.addTodo = function(todoText) {

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore("todo");

  var request = store.put({

    "text": todoText,

    "timeStamp" : new Date().getTime()

  });

 

  request.onsuccess = function(e) {

    // Re-render all the todo's

    html5rocks.indexedDB.getAllTodoItems();

  };

 

  request.onerror = function(e) {

    console.log(e.value);

  };

};addTodo方法特别轻便,大家首先猎取数据库对象的全速援用,初步化READ_W卡宴ITE事务,并收获大家对象存款和储蓄的引用。

 

既然如此使用有权访问对象存款和储蓄,大家就足以经过基础JSON 对象发出简短的put命令。请小心timeStamp属性,那是目的的独一密钥,并视作“keyPath”使用。put调用成功后,会触发onsuccess事件,然后大家就能够在荧屏上显现内容了。

 

第 4步:查询存款和储蓄中的数据。

既是数据现已在数据库中了,大家就必要通过某种方式以有意义的诀窍访问数据。幸运的是,那样的章程特别轻便直接:

 

[html] 

html5rocks.indexedDB.getAllTodoItems = function() {    var todos = document.getElementById("todoItems");    todos.innerHTML = "";      var db = html5rocks.indexedDB.db;    var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);    var store = trans.objectStore("todo");      // Get everything in the store;    var keyRange = IDBKeyRange.lowerBound(0);    var cursorRequest = store.openCursor(keyRange);      cursorRequest.onsuccess = function(e) {      var result = e.target.result;      if(!!result == false)        return;        renderTodo(result.value);      result.continue();    };      cursorRequest.onerror = html5rocks.indexedDB.onerror;  };  html5rocks.indexedDB.getAllTodoItems = function() {

  var todos = document.getElementById("todoItems");

  todos.innerHTML = "";

 

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore("todo");

 

  // Get everything in the store;

  var keyRange = IDBKeyRange.lowerBound(0);

  var cursorRequest = store.openCursor(keyRange);

 

  cursorRequest.onsuccess = function(e) {

    var result = e.target.result;

    if(!!result == false)

      return;

 

    renderTodo(result.value);

    result.continue();

  };

 

  cursorRequest.onerror = html5rocks.indexedDB.onerror;

};请小心,本例中央银行使的全数这几个命令都以异步的,由此数据不是从事务内部重返的。

 

该代码可调换事务,并将对此数据的 keyRange搜索实例化。keyRange定义了大家要从存储中查询的轻易数据子集。借使存款和储蓄的keyRange是数字时间戳,大家应将寻找的细微值设为0(时间原点后的另外时刻),那样就能够回来全部数据。

 

未来大家有了事情、对要查询的囤积的援引以及要迭代的界定。剩下的行事就是张开指针并附加“onsuccess”事件了。

 

结果会传送到对指针的功成名就回调,并在里头表现。对于各种结果只会运转三回回调,因而请必需持续迭代您要求的多寡,以担保对结果对象调用“continue”。

 

第 4 步:展现对象存款和储蓄中的数据

从指标存款和储蓄中抓取了数码后,将对指针中的种种结果调用renderTodo方法。

 

[html] 

function renderTodo(row) {    var todos = document.getElementById("todoItems");    var li = document.createElement("li");    var a = document.createElement("a");    var t = document.createTextNode();    t.data = row.text;      a.addEventListener("click", function(e) {      html5rocks.indexedDB.deleteTodo(row.text);    });      a.textContent = " [Delete]";    li.appendChild(t);    li.appendChild(a);    todos.appendChild(li)  }  function renderTodo(row) {

  var todos = document.getElementById("todoItems");

  var li = document.createElement("li");

  var a = document.createElement("a");

  var t = document.createTextNode();

  t.data = row.text;

 

  a.addEventListener("click", function(e) {

    html5rocks.indexedDB.deleteTodo(row.text);

  });

 

  a.textContent = " [Delete]";

  li.appendChild(t);

  li.appendChild(a);

  todos.appendChild(li)

}对于某些内定的待办事项,大家只必要获得文本并为其创设顾客分界面(包涵“删除”开关,以便除去待办事项)。

 

第 5步:删除表格中的数据

[html] 

html5rocks.indexedDB.deleteTodo = function(id) {    var db = html5rocks.indexedDB.db;    var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);    var store = trans.objectStore("todo");      var request = store.delete(id);      request.onsuccess = function(e) {      html5rocks.indexedDB.getAllTodoItems();  // Refresh the screen    };      request.onerror = function(e) {      console.log(e);    };  };  html5rocks.indexedDB.deleteTodo = function(id) {

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore("todo");

 

  var request = store.delete(id);

 

  request.onsuccess = function(e) {

    html5rocks.indexedDB.getAllTodoItems();  // Refresh the screen

  };

 

  request.onerror = function(e) {

    console.log(e);

  };

};正如将数据 put到指标存款和储蓄中的代码同样,删除数据也不会细小略。运转一个事务,通过对象援用对象存款和储蓄,然后通过对象的独一ID发出delete命令。

 

第 6步:整体涉嫌起来

在加载网页时,打开数据库并创设表格(如有要求),然后突显数据库中大概已存在的其他待办事项。

 

[html] 

function init() {    html5rocks.indexedDB.open(); // open displays the data previously saved  }    window.addEventListener("DOMContentLoaded", init, false);  function init() {

  html5rocks.indexedDB.open(); // open displays the data previously saved

}

 

window.add伊芙ntListener("DOMContentLoaded", init, false);那必要用到可将数据抽取 DOM的函数,即 html5rocks.indexedDB.addTodo方法: 

 

[html] 

function addTodo() {    var todo = document.getElementById('todo');      html5rocks.indexedDB.addTodo(todo.value);  

IndexedDB是HTML5中的新添效果与利益。互联网数据库托管并留存在客户的浏览器内。只要让开采人士通过抬高的询问作用创制应用,就足以预认为...

本文由永利集团登录网址发布于web资讯,转载请注明出处:深入解析HTML5中的IndexedDB索引数据库,html5indexe

关键词: