禁止转载,WEB应用在用户浏览器端存储数据

从数据库中除去数据

剔除数据利用delete方法,同上临近:

var request = db.transaction([‘movies’], ‘readwrite’)
.objectStore(‘movies’) .delete(‘27054612’); // 通过键id来删除
request.onsuccess = function(event) { console.log(‘删除成功!’);
console.log(event.target.result); };

1
2
3
4
5
6
7
8
var request =
    db.transaction([‘movies’], ‘readwrite’)
      .objectStore(‘movies’)
      .delete(‘27054612’);  // 通过键id来删除
request.onsuccess = function(event) {
    console.log(‘删除成功!’);
    console.log(event.target.result);
};

 

积攒数据

存款和储蓄数据有三种格局:add()方法put()方法

那三种方法的区分重要反映在:当要增加数据的靶子存款和储蓄空间中早就存在有肖似键的多寡时,使用add()方法增添数据会报错误,而put()方法规会对现存数量实行校正,所以add()方法平常用来起头化数据,而put()方法用于更新数据

代码如下:

// customerData 为要存储的数据
const customerData = [{ ssn: '444-44-4444', name: 'AAA', age: 35, email: '[AAA@company.com](mailto:AAA@company.com)'},{ ssn: '666-66-6666', name: 'CCC', age: 35, email: '[CCC@company.com](mailto:CCC@company.com)'},{ ssn: '777-77-7777', name: 'DDD', age: 32, email: '[DDD@home.org](mailto:DDD@home.org)'},{ ssn: '555-55-5555', name: 'BBB', age: 32, email: '[BBB@home.org](mailto:BBB@home.org)'},
];

// 创建一个事务,该事务将要对名为“customers”的对象存储空间进行 read和write 操作,并返回事务索引
let transaction = db.transaction('customers', 'readwrite'); 

// 取得索引后,使用objectStore()方法并传入存储空间的名称,就可以访问特定的存储空间,这两步是必须的
let store = transaction.objectStore('customers'); 

// 添加数据到数据库中
for (var i in customerData) {
  // 返回的req也是一个对象,可以为其添加onsuccess和onerror事件,来检测数据是否添加成功
  let req = store.put(customerData[i]);   // 往一个存储空间中添加数据

}
// 判断事务整个操作完成
transaction.oncomplete = function(event) {
  console.log(event.target);
  alert('存储数据完成');
};
}

如上就将数据存款和储蓄到数据库dbNames的customers对象存款和储蓄空间中

地点代码中涉及了
[事务],这里先记住:凡是涉及到对数据库的读写删除操作,都亟需经过
[事务] 来完成

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

那篇小说首要介绍了深切剖析HTML5中的IndexedDB索引数据库,包蕴事务锁等根底用的连带应用示例,要求的爱侣能够参见下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5
WEB应用在顾客浏览器端存款和储蓄数据。对于使用来讲IndexedDB特别苍劲、有用,能够在客商端的chrome,IE,Firefox等WEB浏览器中存放多量数量,下边简要介绍一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的数目存款和储蓄,能够在客商端存款和储蓄、操作数据,能够使应用加载地更加快,越来越好地响应。它差异于关系型数据库,具备数据表、记录。它影响着大家两全和创办应用程序的不二等秘书籍。IndexedDB
创造有数据类型和简易的JavaScript持久对象的object,每一个object能够有目录,使其立见成效地询问和遍历整个集合。本文为你提供了怎么在Web应用程序中利用IndexedDB的真正事例。
 
开始 大家需求在实施前满含下前面置代码

JavaScript
Code复制内容到剪贴板

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

 
打开IndexedDB 在开创数据库早前,我们第生机勃勃需求为数据库创立数量,借使大家犹如下的客户消息:

JavaScript
Code复制内容到剪贴板

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

前几天大家供给用open()方法展开我们的数据库:

JavaScript
Code复制内容到剪贴板

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

如上所示,大家早已展开了名称为”databaseName”,内定版本号的数据库,open()方法有七个参数:
1.率先个参数是数据库名称,它会质量评定名字为”databaseName”的数据库是不是业已存在,若是存在则张开它,不然创制新的数据库。
2.次之个参数是数据库的本子,用于客户更新数据库结构。
 
onSuccess处理 发生成功事件时“onSuccess”被触发,借使具备成功的央求都在那管理,大家得以经过赋值给db变量保存诉求的结果供今后使用。
 
onerror的管理程序 发出错误事件时“onerror”被触发,借使打开数据库的长河中告负。
 
Onupgradeneeded管理程序 假如你想翻新数据库(创制,删除或更动数据库卡塔 尔(阿拉伯语:قطر‎,那么你必得得以完成onupgradeneeded管理程序,让你能够在数据库中做其余改换。
在“onupgradeneeded”管理程序中是能够改善数据库的组织的独步天下地点。
 
创设和增加数据到表:
IndexedDB使用对象存款和储蓄来囤积数据,并非通过表。
每当叁个值存款和储蓄在对象存款和储蓄中,它与二个键相关联。
它同意大家创设的其它对象存款和储蓄索引。
索引允许大家探问存储在目标存款和储蓄中的值。
下边包车型客车代码展现了哪些创制对象存款和储蓄并插入预先计划好的数据:

JavaScript
Code复制内容到剪贴板

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

大家利用createObjectStore(卡塔 尔(英语:State of Qatar)方法创造贰个目标存储。 此方法选择四个参数:

  • 存款和储蓄的称号和参数对象。
    在这处,我们有贰个名称为”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. <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事务管理。可是结果就分歧

图片 1

测验的时候b.html中大概不会应声有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了事情丢队列中等待。不过无论如何,输出结果也不会是1以此值。因为indexedDB的十分小管理单位是业务,并非localStorage那样以表明式为单位。那样只要把lock和unlock之间必要管理的事物归入八个职业中就能够达成。别的,浏览器对indexedDB的支撑不比localStorage,所以采纳时还得构思浏览器宽容。

那篇文章重要介绍了尖锐深入剖判HTML5中的IndexedDB索引数据库,富含事务锁等基本成效的有关使…

总结

可以知道,在Web应用中选拔离线数据实际不是十二分复杂。希望经过阅读这篇小说,各位能够在Web应用中参与离线数据的法力,使得你们的行使尤其温馨易用。你能够在这里下载全体的源码,尝试一下,大概改革,可能用在你们的运用中。

赞 收藏
评论

在目录上应用游标

接着本文上述使用索引的事例,在目录title上使用openCursor()措施时,若不传参数,则会遍历全数数据,在功成名就回调中的到的result指标有以下属性:

  • key 数据库中那条对象的title属性值
  • primaryKey 数据库中那条对象的alt
  • value 数据库中那条对象
  • direction openCursor()方法传入的第四个目标,暗中同意值为next
  • source IDBIndex对象 举个例子如下:
var index = db .transaction('movies')
.objectStore('movies').index('title'); index.openCursor().onsuccess
= function(event) { var cursor = event.target.result; if (cursor) {
console.log('cursor:', cursor); cursor.continue(); } };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f37afae763506229096-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f37afae763506229096-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f37afae763506229096-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f37afae763506229096-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f37afae763506229096-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f37afae763506229096-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f37afae763506229096-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f37afae763506229096-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f37afae763506229096-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f37afae763506229096-10">
10
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f37afae763506229096-1" class="crayon-line">
var index = db
</div>
<div id="crayon-5b8f37afae763506229096-2" class="crayon-line crayon-striped-line">
.transaction('movies')
</div>
<div id="crayon-5b8f37afae763506229096-3" class="crayon-line">
.objectStore('movies').index('title');
</div>
<div id="crayon-5b8f37afae763506229096-4" class="crayon-line crayon-striped-line">
index.openCursor().onsuccess = function(event) {
</div>
<div id="crayon-5b8f37afae763506229096-5" class="crayon-line">
  var cursor = event.target.result;
</div>
<div id="crayon-5b8f37afae763506229096-6" class="crayon-line crayon-striped-line">
  if (cursor) {
</div>
<div id="crayon-5b8f37afae763506229096-7" class="crayon-line">
      console.log('cursor:', cursor);
</div>
<div id="crayon-5b8f37afae763506229096-8" class="crayon-line crayon-striped-line">
      cursor.continue();
</div>
<div id="crayon-5b8f37afae763506229096-9" class="crayon-line">
  }
</div>
<div id="crayon-5b8f37afae763506229096-10" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>


[![](http://jbcdn2.b0.upaiyun.com/2017/12/5451a2dedd05d9226415141022934c72.png)](http://jbcdn2.b0.upaiyun.com/2017/12/5451a2dedd05d9226415141022934c72.png)

在索引title上使用openKeyCursor()措施,若不传参数,相似也会遍历全数数据,result对象属性如下:

  • key 数据库中那条对象的title属性值
  • primaryKey 数据库中那条对象的alt
  • direction openCursor()方法传入的第3个目的,暗许值为next
  • source altBIndex对象

openCursor()措施比较,获得的数额少多个value性情,是绝非艺术得到存款和储蓄对象的其他部分

前方聊到,大家要依靠目录title拿到具备title属性值为寻梦环游记的指标,要动用游标,而又不想遍历全部数据,这个时候就要选择openCursor()的率先个参数:
keyRange

keyRange是限量游标遍历的数量范围,通过IDBKeyRange的部分方法设置该值:

var singleKeyRange = IDBKeyRange.only(“寻梦环游记”), list = []; var
index = db .transaction(‘movies’) .objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange).onsuccess = function(event) { var
cursor = event.target.result; if (cursor) { console.log(‘cursor.value:’,
cursor.value); list.push(cursor.value); cursor.continue(); } else {
console.log(‘list:’, list); } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var singleKeyRange = IDBKeyRange.only("寻梦环游记"), list = [];
var index = db
.transaction(‘movies’)
.objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(‘cursor.value:’, cursor.value);
list.push(cursor.value);
cursor.continue();
} else {
    console.log(‘list:’, list);
}
};

图片 2

IDBKeyRange其余部分情势:

// 相称全数在 “Bill” 前边的, 包含 “Bill” var lowerBoundKeyRange =
IDBKeyRange.lowerBound(“Bill”); // 相配全体在 “Bill” 前面包车型地铁,
不过没有必要包蕴 “Bill” var lowerBoundOpenKeyRange =
IDBKeyRange.lowerBound(“Bill”, true); // 相配全体在’Donna’后边的,
可是不满含”Donna” var upperBoundOpenKeyRange =
IDBKeyRange.upperBound(“Donna”, true); // 相称全数在”Bill” 和 “Donna”
之间的, 然而不包涵 “Donna” var boundKeyRange = IDBKeyRange.bound(“Bill”,
“Donna”, false, true);

1
2
3
4
5
6
7
8
9
10
11
// 匹配所有在 "Bill" 前面的, 包括 "Bill"
var lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill");
 
// 匹配所有在 “Bill” 前面的, 但是不需要包括 "Bill"
var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true);
 
// 匹配所有在’Donna’后面的, 但是不包括"Donna"
var upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna", true);
 
// 匹配所有在"Bill" 和 "Donna" 之间的, 但是不包括 "Donna"
var boundKeyRange = IDBKeyRange.bound("Bill", "Donna", false, true);

越多请参考
MDN|IDBKeyRange

游标暗中同意遍历方向是按主键从小到大,不时候大家倒序遍历,那时得以给openCursor()艺术传递第一个参数:
direction: next|nextunique|prev|prevunique

var singleKeyRange = IDBKeyRange.only(“寻梦环游记”), list = []; var
index = db .transaction(‘movies’) .objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange, ‘prev’).onsuccess = function(event) {
var cursor = event.target.result; if (cursor) {
console.log(‘cursor.value:’, cursor.value); list.push(cursor.value);
cursor.continue(); } else { console.log(‘list:’, list); } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var singleKeyRange = IDBKeyRange.only("寻梦环游记"), list = [];
var index = db
.transaction(‘movies’)
.objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange, ‘prev’).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(‘cursor.value:’, cursor.value);
list.push(cursor.value);
cursor.continue();
} else {
    console.log(‘list:’, list);
}
};

传了prev的结果是按倒序遍历的.

因为 “name” 索引不是唯风流罗曼蒂克的,那就有非常大可能率存在具备相像 name 的多条记下。
要小心的是这种景象不大概产生在对象存款和储蓄空间上,因为键必得长久是头一无二的。
假若您想要在游标在目录迭代进度中过滤出重新的,你能够传递
nextunique(或prevunique, 假设你正在向后查找)作为方向参数。 当
nextunique 或是 prevunique
被接纳时,被重回的不胜总是键最小的记录。

var singleKeyRange = IDBKeyRange.only(“寻梦环游记”), list = []; var
index = db .transaction(‘movies’) .objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange, ‘prevunique’).onsuccess =
function(event) { var cursor = event.target.result; if (cursor) {
console.log(‘cursor.value:’, cursor.value); list.push(cursor.value);
cursor.continue(); } else { console.log(‘list:’, list); } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var singleKeyRange = IDBKeyRange.only("寻梦环游记"), list = [];
var index = db
.transaction(‘movies’)
.objectStore(‘movies’).index(‘title’);
index.openCursor(singleKeyRange, ‘prevunique’).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(‘cursor.value:’, cursor.value);
list.push(cursor.value);
cursor.continue();
} else {
    console.log(‘list:’, list);
}
};

图片 3

介绍

IndexedDB便是三个数据库
其最大的性状是:
行使对象保存数据,并不是运用表来保存数据,相同的时间,它是异步的

示例

小编们无妨来探歌后边的例子。在联系人和评价的一些,大家能够随即保存顾客输入的东西。这样一来,尽管客商非常大心关闭了浏览器,从前输入的事物也不会废弃。对于jQuery来讲,那一个作用是小菜一碟。(注意:表单中种种输入字段都有id,在这里边大家就用id来代表具体的字段卡塔尔

JavaScript

$(‘#comments-input, .contact-field’).on(‘keyup’, function () { // let’s
check if localStorage is supported if (window.localStorage) {
localStorage.setItem($(this).attr(‘id’), $(this).val()); } });

1
2
3
4
5
6
$(‘#comments-input, .contact-field’).on(‘keyup’, function () {
   // let’s check if localStorage is supported
   if (window.localStorage) {
      localStorage.setItem($(this).attr(‘id’), $(this).val());
   }
});

历次提交联系人和评价的表单,大家须求清空缓存的值,我们得以那样管理提交(submit卡塔 尔(阿拉伯语:قطر‎事件:

JavaScript

$(‘#comments-form, #contact-form’).on(‘submit’, function () { // get
all of the fields we saved $(‘#comments-input,
.contact-field’).each(function () { // get field’s id and remove it from
local storage localStorage.removeItem($(this).attr(‘id’)); }); });

1
2
3
4
5
6
7
$(‘#comments-form, #contact-form’).on(‘submit’, function () {
   // get all of the fields we saved
   $(‘#comments-input, .contact-field’).each(function () {
      // get field’s id and remove it from local storage
      localStorage.removeItem($(this).attr(‘id’));
   });
});

最终,每回加载页面包车型客车时候,把缓存的值填充到表单上就能够:

JavaScript

// get all of the fields we saved $(‘#comments-input,
.contact-field’).each(function () { // get field’s id and get it’s value
from local storage var val = localStorage.getItem($(this).attr(‘id’));
// if the value exists, set it if (val) { $(this).val(val); } });

1
2
3
4
5
6
7
8
9
// get all of the fields we saved
$(‘#comments-input, .contact-field’).each(function () {
   // get field’s id and get it’s value from local storage
   var val = localStorage.getItem($(this).attr(‘id’));
   // if the value exists, set it
   if (val) {
      $(this).val(val);
   }
});

五、使用索引

在前边,大家创立了多少个目录alttitle,
配置对象里面包车型大巴unique质量标识该值是不是唯意气风发

当今大家想找到alt属性值为https://movie.douban.com/subject/26639033/的对象,就可以利用索引。

var alt = ”; var objectStore
= db.transaction(‘movies’).objectStore(‘movies’); // 展开对象存款和储蓄空间
var index = objectStore.index(‘alt’); // 使用索引’alt’ var request =
index.get(alt); // 创建二个查找数据的呼吁 request.onsuccess =
function(event) { console.log(‘The result is:’, event.target.result); };
var noDataTest = index.get(‘testalt’); // 未有该对象时的测试noDataTest.onsuccess = function(event) { console.log(‘success! result:’,
event.target.result); }; noDataTest.onerror = function(event) {
console.log(‘error! event:’, event); };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var alt = ‘https://movie.douban.com/subject/26639033/’;
var objectStore = db.transaction(‘movies’).objectStore(‘movies’);  // 打开对象存储空间
var index = objectStore.index(‘alt’);  // 使用索引’alt’
var request = index.get(alt);          // 创建一个查找数据的请求
request.onsuccess = function(event) {
    console.log(‘The result is:’, event.target.result);
};
var noDataTest = index.get(‘testalt’);  // 没有该对象时的测试
noDataTest.onsuccess = function(event) {
    console.log(‘success! result:’, event.target.result);
};
noDataTest.onerror = function(event) {
    console.log(‘error! event:’, event);
};

图片 4

使用唯风流倜傥性索引,大家得以获得唯意气风发的一条数据(恐怕undefined),那么使用非唯意气风发性索引呢?
咱俩向数据库中插入一条数据,使title重复:

db.transaction(‘movies’, ‘readwrite’).objectStore(‘movies’) .add({ alt:
”, title: ‘寻梦环游记’,
year: ‘2017’, id: ‘123456789’ }) .onsuccess = function(event) {
console.log(‘插入成功!’); };

1
2
3
4
5
6
7
db.transaction(‘movies’, ‘readwrite’).objectStore(‘movies’)
.add({ alt: ‘https://movie.douban.com/subject/27054612121/’,
    title: ‘寻梦环游记’,
    year: ‘2017’,
    id: ‘123456789’
})
.onsuccess = function(event) { console.log(‘插入成功!’); };

接收索引title获取title值为寻梦环游记的对象:

var indexName = ‘title’, title = ‘寻梦环游记’; var objectStore =
db.transaction(‘movies’).objectStore(‘movies’); var index =
objectStore.index(indexName); // 使用索引’alt’ var request =
index.get(title); // 创制二个物色数据的央浼 request.onsuccess =
function(event) { console.log(‘The result is:’, event.target.result); };

1
2
3
4
5
6
7
var indexName = ‘title’, title = ‘寻梦环游记’;
var objectStore = db.transaction(‘movies’).objectStore(‘movies’);
var index = objectStore.index(indexName);  // 使用索引’alt’
var request = index.get(title);          // 创建一个查找数据的请求
request.onsuccess = function(event) {
    console.log(‘The result is:’, event.target.result);
};

图片 5

咱俩收获的是键值细微的不胜对象.

使用一次索引,我们只可以得到一条数据;
假设大家需求拿到全部title属性值为寻梦环游记的指标,大家可以动用游标.

indexDB.open()方法的规律

分成三种意况:
1. 传诵的数据库荒诞不经
当传入的数据库不设偶然,该方法就能创设二个名称叫name的数据库,并开辟它,当时,会先触发upgradeneeded事件;调用该函数会重临叁个IDBRequest指标,能够在该指标上增加onsuccess事件onerror事件
注意:当展开一个不真实的数据库时会触发upgradeneeded事件,那是触发该事件的黄金年代种门路,为啥会触发该事件吧?该事件有哪些功效?留个疑问在此刻,等会解答。

2. 流传的数据仓库储存在
此间分为二种状态:

  • 当传入的数据仓库储存在,且version版本号与将要张开的数据库版本号也同样
    则一向张开该数据库,要是成功,则会接触onsuccess事件,退步则触发onerror事件
    注意:这里并不会接触upgradeneeded事件,为何?留个问号

  • 当传入的数据仓库储存在,不过传入的version版本号高于将要张开的数据库的版本号
    则一贯展开该数据库,同不日常候触发upgradeneeded事件,然后再接触onsuccess事件onerror事件,这里也接触了onupdateneeded事件

本文由 伯乐在线 –
njuyz
翻译。未经许可,禁止转发!
波兰语出处:Nettuts+。招待参预翻译组。

六、使用游标

收获四个得以操作游标的伸手对象有八个方法:

  • openCursor(keyRange, direction)
  • openKeyCursor(keyRange, direction)
    那四个点子选拔的参数相似, 四个参数都是可选的:
    第三个参数是限量值得范围,第2个参数是点名游标方向

游标的接受有以下几处:

  • 在目的存款和储蓄空间上选择: var cursor = objectStore.openCursor()
  • 在目录对象上行使: var cursor = index.openCursor()

键范围

游标也足以担当多个键,也正是由此键来设定游标查找的范围;
代码如下:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>WebStorage DEMO</title>
</head>
<body>
<div class=”networkStatus”>
<button class=”clear”>清空数据</button>
<button class=”add”>增加数量</button>
<button class=”query”>查询数据</button>
<button class=”delete”>删除数据</button>
<button class=”cursor”>使用游标查询</button>
<button class=”keyRange”>使用keyrange查询</button>
<button class=”index”>使用index</button>
</div>

<script>
let network = document.querySelector(‘.networkStatus’),
addBtn = document.querySelector(‘.add’),
queryBtn = document.querySelector(‘.query’),
deleteBtn = document.querySelector(‘.delete’),
cursorBtn = document.querySelector(‘.cursor’),
clearBtn = document.querySelector(‘.clear’),
keyRange = document.querySelector(‘.keyRange’),
indexBtn = document.querySelector(‘.index’)
;

// 推断网路是还是不是在线
// if (navigator.onLine) {
// network.innerText = “网络在线”;
// } else {
// network.innerText = “互连网掉线”;
// }

// // 监察和控制网络状态的事件:online 和 offline, 那八个事件在window对象上
// window.addEventListener(‘online’, () => {
// network.innerText = “互连网在线”;
// });

// window.addEventListener(‘offline’, () => {
// network.innerText = “网络掉线”;
// });

//——–cookie的使用—————
let CookieUtil = {
get: (name) => {
let cookieName = encodeURIComponent(name) + “=”,
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;

  if (cookieStart > -1) {
    let cookieEnd = document.cookie.indexOf(';', cookieStart);
    if (cookieEnd === -1) {
      cookieEnd = document.cookie.length;
    }
    cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
  }

  return cookieValue;
},
set: function (name, value, expires, path, domain, secure) {
  let cookieText = encodeURIComponent(name) + '=' +
                   encodeURIComponent(value);

  if (expires instanceof Date) {
    cookieText += '; expires=' + expires.toGMTString();
  }

  if (path) {
    cookieText += '; path=' + path;
  }

  if (domain) {
    cookieText += '; domain=' + domain;
  }

  if (secure) {
    cookieText += '; secure';
  }

  document.cookie = cookieText;
},

// 删除cookie, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
// 同时 将过期时间expires设置为过去的时间,
unset: function(name, path, domain, secure) {
  this.set(name, '', new Date(0), path, domain, secure);
}

}

CookieUtil.set(‘name’, ‘hexon’);
CookieUtil.set(‘book’, ‘Profession Javascript’);

// 读取cookie的值
// console.log(CookieUtil.get(‘name’));
// console.log(CookieUtil.get(‘book’));

// 删除cookie
CookieUtil.unset(‘name’);
CookieUtil.unset(‘book’);

// 设置cookie, 包含它的路子、域、失效日期
CookieUtil.set(‘name’, ‘Hexon’, ‘books/projs/’,
‘www.wrox.com’, new
Date(‘January 1, 2017’));

// 删除刚刚安装的cookie
CookieUtil.unset(‘name’, ‘books/projs/’,
‘www.www.wrox.com’);

// 设置安全的cookie
CookieUtil.unset(‘name’, ‘hexon’, null, null, null, null, true)

// — IndexedDB 数据库的行使
var request = window.indexedDB.open(‘dbName’, 2)
var db;
const dbName = ‘the_name’;
// 创立多个数码
const customerData = [
{ ssn: ‘444-44-4444’, name: ‘AAA’, age: 35, email:
‘AAA@company.com’},
{ ssn: ‘666-66-6666’, name: ‘CCC’, age: 35, email:
‘CCC@company.com’},
{ ssn: ‘777-77-7777’, name: ‘DDD’, age: 32, email:
‘DDD@home.org’},
{ ssn: ‘555-55-5555’, name: ‘BBB’, age: 32, email:
‘BBB@home.org’},

];

window.indexedDB = window.indexedDB || window.msIndexedDB ||
window.mozIndexedDB || window.webkitIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE:
“readwrite”};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange ||
window.msIDBKeyRange;
window.IDBCursor = window.IDBCursor || window.webkitIDBTransaction;

if (!window.indexedDB) {
window.alert(“Your browser doesn’t support a stable version of
IndexedDB.”)
}

// 3
是建构的数据库版本,假如名称为MyTestDatabase的数据库不设有,就能创建该数据库,然后
onupgradeneeded 事件会被触发;
// 即使数据库存在,然则对版本进级了,也会触发onupgradeneeded事件,
// 注意:版本号是七个 unsigned long long
类型的值,由此不用选择float,不然会将其转移为其最相通的莫西干发型

// 生成管理程序
request.onerror = function (event) {
// do Something
alert(‘Database error: ‘ + event.target.errorCode);
};

request.onsuccess = function (event) {
// do Something
console.log(‘创设数据库成功’);
db = event.target.result; // 创制作而成功后,e.target.result
中蕴藏的是IDBDatabase对象的实例
}

// 当创制四个新的数额库 大概 更新已存在数据库的版本,
onupgradeneeded事件将会被触发,新的目的存款和储蓄在event.target.result中。
//
在该管理程序中,数据库已经持有先前版本的对象存款和储蓄,由此无需再一次创制那些目的存款和储蓄,只供给创设任何大家须要的靶子存款和储蓄,也许
//
从先前版本中除去不在需求的靶子存款和储蓄。若是须要转移当前指标存款和储蓄,则必需先删除旧的目的存款和储蓄,然后在运用新的选项创制。
// 删除旧的靶子存储,在其上的新闻都会被剔除;
//
注意:该事件是举世无双八个能力所能达到对数据库举行操作的地点,在该事件之中,你对指标存款和储蓄举行删减、更正或移除索引
request.onupgradeneeded = function(event) {
console.log(‘onupgradeneeded’);
var db = event.target.result;

// 创建一个   对象存储空间,名为customers
var objectStore = db.createObjectStore('customers', {keyPath: 'ssn'});
// 对于某些数据,可以为一个对象存储空间指定多个键。比如,若要通过用户ID 和用户名 两种方式来保存用户资料,就需要通过两个键来存取记录
// 因此可以使用createIndex,名字是有可能重复的,所以其unique 设置为 false ;第一个name是索引的名字,该名字是索引的名字,第二个name是索引的属性的名字,该名字要与对象中的属性相同
objectStore.createIndex('name', 'name', { unique: false});

// // 创建一个email的索引,该email是独特的,所以 unique 设置为 true
objectStore.createIndex('email', 'email', { unique: true});

}

function save(data) {
///
对于数据库的目的存款和储蓄空间中多少的读取或改造数据,都要通过事物来协会具备操作
// 最简易的创制事物的点子是:var transaction = db.transaction();
let transaction = db.transaction(‘customers’, ‘readwrite’); //
创造多少个思想政治工作,并定义该业务的操作为 “readwrite” ,并重临其索引
let store = transaction.objectStore(‘customers’); //
得到索引后,使用objectStore()方法并传到存款和储蓄空间的称谓,就可以访问特定的囤积空间

for (var i in customerData) {
  let req = store.put(customerData[i]);   // 往一个存储空间中添加数据
}

transaction.oncomplete = function(event) {
  console.log(event.target);
  alert('存储数据完成');
};

transaction.onsuccess = function(event ) {
  console.log('onsuccess 事件');
}

}

function clear() {
// body…
let transaction = db.transaction(‘customers’, ‘readwrite’);
let store = transaction.objectStore(‘customers’).clear();
store.onerror = function(event) {
console.log(‘清空数据战败’);
}
store.onsuccess = function(event) {
console.log(‘清空数据成功’);
}
}

// 使用事务 间接通过已知的键索引 单个对象 (只可以索引单个对象卡塔尔
function getData() {
let transaction = db.transaction(‘customers’, ‘readwrite’); //
成立一个东西, 并定义该业务的操作为 “readonly”
let store = transaction.objectStore(‘customers’).get(‘444-44-4444’); //
使用get() 能够收获值

store.onerror = function (event) {
  alert('did not get the object');
}

store.onsuccess = function (event) {
  var result = event.target.result;
  console.log(result);
  alert('获取数据完成! 年龄是: ' + result.age);
}

}

function deleteData() {
let transaction = db.transaction(‘customers’, ‘readwrite’);
let store = transaction.objectStore(‘customers’);
store.delete(‘444-44-4444’);
alert(‘s删除数据形成’);
}

// 在事行业内部创立游标查询 可以索引 几个目的(注意: 是多个目的卡塔 尔(英语:State of Qatar)
// 游标不提前手机结果
function cursorQuery() {
let transaction = db.transaction(‘customers’, ‘readwrite’),
store = transaction.objectStore(‘customers’),
request = store.openCursor(null) ; // 这里创办游标

request.onsuccess = function (event) {

  // event.target.result 中保存的是在存储空间中查询到的对象
  // event.target.result 中有几个属性值,可以了解到查询到的对象中的细节,
  // key: 当前访问的对象的键
  // value:当前访问的实际对象
  // primaryKey: 游标使用的键
  // direction:数值,表示游标移动的方向

  let cursor = event.target.result;
  let value, updateRequest, deleteRequest;
  if (cursor) {
  //   if (cursor.key === '555-55-5555') {
  //     value = cursor.value;   // 获取到实际的访问对象
  //     value.name = 'hexon';   // 修改对象的name属性

  //     updateRequest = cursor.update(value);      // 调用update()方法可以用指定的对象,更新对象的value
  //     updateRequest.onsuccess = function() {
  //       // 处理成功
  //     }
  //     updateRequest.onerror = function() {
  //       // 处理失败
  //     }


  //     // 使用游标删除当前项
  //     // deleteRequest = cursor.delete();
  //     // deleteRequest.onsuccess = function() {
  //     //   // 删除成功处理
  //     // }
  //     // deleteRequest.onerror = function() {
  //     //   // 删除失败处理
  //     // }


  //   }
  //   console.log(event.target.result);
  // }
  console.log(cursor.value);
  cursor.continue();      // 移动到下一项,
  }
  request.onerror = function(event) {
    console.log('游标查询创建失败')
  }
}

}

// 使用keyrange查询
function keyRangeQuery() {
let transaction = db.transaction(‘customers’, ‘readwrite’)
let store = transaction.objectStore(‘customers’);
// 使用bound()方法 定义键范围
let range = IDBKeyRange.bound(‘555-55-5555’, ‘777-77-7777’, true,
false);
// 将键传入游标创设
let request = store.openCursor(range);

request.onsuccess = function(event) {
  let cursor = event.target.result;
  if (cursor) {
    console.log('游标查询到的值' + JSON.stringify(cursor.value));
    cursor.continue()     // 移动到下一项
  }

}

request.onerror = function(event) {
  console.log("使用游标 + keyrange 查询失败")
}

}

// 使用索引
function useIndex() {
let store = db.transaction(‘customers’).objectStore(‘customers’),
index = store.index(‘name’);
request = index.openCursor();
request.onsuccess = function (event) {
let cursor = event.target.result;
if (cursor) {
console.log(cursor);
cursor.continue();
}
}
}

addBtn.addEventListener(‘click’, function(e) {
save();
}, false);

deleteBtn.addEventListener(‘click’, function(e) {
deleteData();
}, false);

queryBtn.addEventListener(‘click’, function(e) {
getData();
}, false);

cursorBtn.addEventListener(‘click’, function(e) {
cursorQuery();
}, false);

clearBtn.addEventListener(‘click’, function(e) {
clear();
}, false);

keyRange.addEventListener(‘click’, function(e) {
keyRangeQuery();
}),

indexBtn.addEventListener(‘click’, function(e) {
useIndex();
})

</script>

</body>
</html>

AppCache

要是您的Web应用中有局地效用(恐怕全体应用卡塔尔国供给在抽离服务器的景观下利用,那么就足以经过AppCache来让您的客商在离线状态下也能使用。你所急需做的正是成立二个安顿文件,在其间钦定哪些能源需求被缓存,哪些不须要。别的,还是可以在里头钦赐有个别联机能源在脱机条件下的代表财富。

AppCache的计划文件日常是三个以.appcache终极的文书文件(推荐写法卡塔尔。文件以CACHE MANIFEST始发,包罗下列三局地内容:

  • CACHE – 钦命了什么能源在顾客率先次访谈站点的时候必要被下载并缓存
  • NETWORK
    钦点了怎么着财富供给在联合条件下本事访谈,这么些能源从不被缓存
  • FALLBACK – 内定了上述资源在脱机条件下的代表财富

发表评论

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

相关文章