菜单

金沙国际深深解析HTML5中的IndexedDB索引数据库,html5indexeddb

2019年2月18日 - 金沙前端

前端的数据库: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:开发者工具查看1个object
store

全副的IndexedDB API请参考完整文档

深远解析HTML5中的IndexedDB索引数据库,html5indexeddb

那篇文章主要介绍了尖锐解析HTML5中的IndexedDB索引数据库,包罗事务锁等基本功用的相干应用示例,需求的心上人可以参考下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5
WEB应用在用户浏览器端存储数据。对于使用来说IndexedDB分外强大、有用,可以在客户端的chrome,IE,Firefox等WEB浏览器中储存多量数码,上边简单介绍一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的多寡存储,可以在客户端存储、操作数据,可以使利用加载地更快,更好地响应。它差距于关系型数据库,拥有数据表、记录。它影响着大家布置和开创应用程序的艺术。IndexedDB
创造有数据类型和精炼的JavaScript持久对象的object,逐个object可以有目录,使其一蹴而就地询问和遍历整个集合。本文为你提供了什么样在Web应用程序中行使IndexedDB的实在事例。
 
开始 我们须要在实践前包含上面前置代码

JavaScript
Code复制内容到剪贴板

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

 
打开IndexedDB 在创制数据库以前,大家先是要求为数据库成立数量,假诺我们有如下的用户新闻:

JavaScript
Code复制内容到剪贴板

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

当今大家须求用open()方法打开大家的数据库:

JavaScript
Code复制内容到剪贴板

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

如上所示,我们早就打开了名为”databaseName”,钦定版本号的数据库,open()方法有三个参数:
1.首先个参数是数据库名称,它会检测名称为”databaseName”的数据库是不是业已存在,假使存在则打开它,否则创造新的数据库。
2.次之个参数是数据库的本子,用于用户更新数据库结构。
 
onSuccess处理 发出成功事件时“onSuccess”被触发,如若拥有成功的哀告都在此处理,我们得以经过赋值给db变量保存请求的结果供将来使用。
 
onerror的处理程序 发出错误事件时“onerror”被触发,借使打开数据库的进程中破产。
 
Onupgradeneeded处理程序 固然你想翻新数据库(创设,删除或改动数据库),那么你必须贯彻onupgradeneeded处理程序,使您可以在数据库中做其余变更。
在“onupgradeneeded”处理程序中是足以变更数据库的布局的绝无仅有地点。
 
成立和添加数据到表:
IndexedDB使用对象存储来囤积数据,而不是通过表。
每当壹个值存储在目的存储中,它与壹个键相关联。
它同意我们创设的任何对象存储索引。
索引允许我们访问存储在对象存储中的值。
上边的代码突显了什么创设对象存储并插入预先准备好的多少:

JavaScript
Code复制内容到剪贴板

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

大家利用createObjectStore()方法成立2个目的存储。 此方法接受八个参数:

JavaScript
Code复制内容到剪贴板

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

事先大家在数据库中做其它的CRUD操作(读,写,修改),必须采取工作。
该transaction()方法是用来内定我们想要举行事务处理的目标存储。
transaction()方法接受三个参数(第二个和第多少个是可选的)。
第二个是咱们要处理的目标存储的列表,第②个钦定咱们是或不是要只读/读写,第陆个是本子变化。
 
从表中读取数据 get()方法用于从目的存储中查找数据。
我们事先已经安装对象的id作为的keyPath,所以get()方法将追寻具有同等id值的靶子。
下边的代码将回来大家命名为“Bidulata”的目的:

JavaScript
Code复制内容到剪贴板

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

 
从表中读取全数数据
上面的法门寻找表中的全部数据。
那里大家使用游标来寻找对象存储中的全数数据:

JavaScript
Code复制内容到剪贴板

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

该openCursor()用于遍历数据库中的三个记录。
在continue()函数中继承读取下一条记下。
删除表中的笔录 上边的艺术从指标中删去记录。

JavaScript
Code复制内容到剪贴板

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

咱俩要将对象的key帕特h作为参数传递给delete()方法。
 
最终代码
上面的章程从目的源中删除一条记下:

JavaScript
Code复制内容到剪贴板

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

localStorage是不带lock成效的。那么要促成前端的数据共享并且须要lock成效那就必要利用此外本储存方式,比如indexedDB。indededDB使用的是事务处理的机制,那实在就是lock作用。
  做那一个测试要求先简单的卷入下indexedDB的操作,因为indexedDB的连接相比较麻烦,而且多少个测试页面都急需用到

JavaScript
Code复制内容到剪贴板

  1. //db.js   
  2. //封装事务操作   
  3. IDBDatabase.prototype.doTransaction=function(f){   
  4.   f(this.transaction([“Obj”],”readwrite”).objectStore(“Obj”));   
  5. };   
  6. //连接数据库,成功后调用main函数   
  7. (function(){   
  8.   //打开数据库   
  9.   var cn=indexedDB.open(“TestDB”,1);   
  10.   //创制数量对象   
  11.   cn.onupgradeneeded=function(e){   
  12.     e.target.result.createObjectStore(“Obj”);   
  13.   };   
  14.   //数据库连接成功   
  15.   cn.onsuccess=function(e){   
  16.     main(e.target.result);   
  17.   };   
  18. })();   
  19.   接着是五个测试页面   
  20. <script src=”db.js”></script>  
  21. <script>  
  22. //a.html   
  23. function main(e){   
  24.   (function callee(){   
  25.     //初叶1个业务   
  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之间须要处理的东西放入2个事情中即可已毕。此外,浏览器对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值。

 

<!DOCTYPE
html>
<html>
  <head>
 
  <style>
 
    body {
 
      color: #222;
 
      font: 14px Arial;
 
    }
 
    
 
    body a {
 
      color: #3D5C9D;
 
      text-decoration: none;
 
    }
 
  </style>
 
  <script>
 
    var html5rocks = {};
 
    window.indexedDB = window.indexedDB || window.webkitIndexedDB ||
 
                       window.mozIndexedDB;
 
    
 
    if (‘webkitIndexedDB’ in window) {
 
      window.IDBTransaction = window.webkitIDBTransaction;
 
      window.IDBKeyRange = window.webkitIDBKeyRange;
 
    }
 
    
 
    html5rocks.indexedDB = {};
 
    html5rocks.indexedDB.db = null;
 
    
 
    html5rocks.indexedDB.onerror = function(e) {
 
      console.log(e);
 
    };
 
    
 
    html5rocks.indexedDB.open = function() {
 
      var request = indexedDB.open(“todos”);
 
    
 
      request.onsuccess = function(e) {
 
        var v = 1;
 
        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.onerror = html5rocks.indexedDB.onerror;
 
          setVrequest.onsuccess = function(e) {
 
            if(db.objectStoreNames.contains(“todo”)) {
 
              db.deleteObjectStore(“todo”);
 
            }
 
    
 
            var store = db.createObjectStore(“todo”,
 
              {keyPath: “timeStamp”});
 
            e.target.transaction.oncomplete = function() {
 
              html5rocks.indexedDB.getAllTodoItems();
 
            };
 
          };
 
        } else {
 
          request.transaction.oncomplete = function() {
 
            html5rocks.indexedDB.getAllTodoItems();
 
          };
 
        }
 
      };
 
      request.onerror = html5rocks.indexedDB.onerror;
 
    };
 
    
 
    html5rocks.indexedDB.addTodo = function(todoText) {
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      var data = {
 
        “text”: todoText,
 
        “timeStamp”: new Date().getTime()
 
      };
 
    
 
      var request = store.put(data);
 
    
 
      request.onsuccess = function(e) {
 
        html5rocks.indexedDB.getAllTodoItems();
 
      };
 
    
 
      request.onerror = function(e) {
 
        console.log(“Error
Adding: “, e);
 
      };
 
    };
 
    
 
    html5rocks.indexedDB.deleteTodo = function(id) {
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      var request = store.delete(id);
 
    
 
      request.onsuccess = function(e) {
 
        html5rocks.indexedDB.getAllTodoItems();
 
      };
 
    
 
      request.onerror = function(e) {
 
        console.log(“Error
Adding: “, e);
 
      };
 
    };
 
    
 
    html5rocks.indexedDB.getAllTodoItems = function() {
 
      var todos = document.getElementById(“todoItems”);
 
      todos.innerHTML = “”;
 
    
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      //
Get everything in the store;
 
      var cursorRequest = store.openCursor();
 
    
 
      cursorRequest.onsuccess = function(e) {
 
        var result = e.target.result;
 
        if(!!result == false)
 
          return;
 
    
 
        renderTodo(result.value);
 
        result.continue();
 
      };
 
    
 
      cursorRequest.onerror = html5rocks.indexedDB.onerror;
 
    };
 
    
 
    function renderTodo(row) {
 
      var todos = document.getElementById(“todoItems”);
 
      var li = document.createElement(“li”);
 
      var a = document.createElement(“a”);
 
      var t = document.createTextNode(row.text);
 
    
 
      a.addEventListener(“click”, function() {
 
        html5rocks.indexedDB.deleteTodo(row.timeStamp);
 
      }, false);
 
    
 
      a.textContent = ”
[Delete]”;
 
      li.appendChild(t);
 
      li.appendChild(a);
 
      todos.appendChild(li);
 
    }
 
    
 
    function addTodo() {
 
      var todo = document.getElementById(“todo”);
 
      html5rocks.indexedDB.addTodo(todo.value);
 
      todo.value = “”;
 
    }
 
    
 
    function init() {
 
      html5rocks.indexedDB.open();
 
    }
 
    
 
    window.addEventListener(“DOMContentLoaded”, init, false);
 
  </script>
  </head>
  <body>
 
  <ul id=”todoItems”></ul>
 
  <input type=”text” id=”todo” name=”todo” placeholder=”What
do you need to do?” style=”width:
200px;” />
 
  <input type=”submit” value=”Add
Todo Item” onclick=”addTodo();
return false;”/>
  </body>
</html>​

依据事务

不一样于一些价值观的关周全据库的兑现,每多少个对数据库操作是在多个工作的上下文中执行的。事务限制两遍影响二个或三个object
stores,你通过传播二个object store名字的数组到开创工作限制的函数来定义。

创制工作的第3个参数是工作模式。当呼吁三个事务时,必须决定是安份守己只读如故读写形式请求访问。事务是能源密集型的,所以一旦您不必要更改data
store中的数据,你只需求以只读格局对object stores集合进行呼吁访问。

清单2演示了怎么样使用合适的方式开创一个业务,并在那片小说的 Implementing
Database-Specific Code
 部分开展了详实谈论。

IndexedDB是什么?

基于请求

以至那里,有3个再三出现的主题,您可能曾经注意到。对数据库的每一回操作,描述为经过三个请求打开数据库,访问1个object
store,再持续。IndexedDB
API天生是依据请求的,那也是API异步本性提示。对于你在数据库执行的每回操作,你不只怕不首先为那一个操作创立三个伸手。当呼吁落成,你可以响应由请求结果爆发的风浪和不当。

本文完毕的代码,演示了何等运用请求打开数据库,创制二个政工,读取object
store的始末,写入object store,清空object store。

IndexedDB是目的存储,它差别于带有表格(包括行和列的联谊)的关周到据库。那是三个要害的根本差异,并且会潜移默化你设计和创设利用的不二法门。

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

IndexedDB使用事件生命周期管理数据库的打开和配置操作。图2演示了1个开拓的请求在放任自流的条件下发出upgrade
need事件。

金沙国际 3

图2:IndexedDB打开请求的生命周期

拥有与数据库的相互开始于四个打开的哀求。试图打开数据库时,您必须传递二个被呼吁数据库的本子号的整数值。在打开请求时,浏览器相比你传入的用于打开请求的版本号与事实上数据库的版本号。假设所请求的版本号高于浏览器中当前的版本号(只怕以后并未存在的数据库),upgrade
needed事件触发。在uprade
need事件时期,你有机会通过添加或移除stores,键和索引来操纵object stores。

假诺所请求的数据库版本号和浏览器的此时此刻版本号相同,恐怕升级进程完结,3个开拓的数据库将回来给调用者。

 

谬误冒泡

自然,有时候,请求或然不会按预想完毕。IndexedDB
API通过荒谬冒泡效果来帮忙跟踪和保管不当。假如二个一定的伸手遭受错误,你可以尝试在伸手对象上处理错误,或然您可以允许错误通过调用栈冒泡向上传递。那么些冒泡特性,使得你不须求为逐个请求已毕特定错误处理操作,而是可以选拔只在1个更高级别上添加错误处理,它给你一个机会,保持您的错误处理代码简洁。本文中贯彻的例子,是在2个高级别处理错误,以便更细粒度操作发生的任何错误冒泡到通用的错误处理逻辑。

在观念的关周密据存储中,大家有三个“待办事项”的表格,其中各行存储了用户待办事项数据的集纳,而各列则是数量的命名类型。要插入数据,日常采纳如下语义:INSE汉兰达TINTO
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是三个客户端数据库,但它当作1个关周全据库的落到实处,使用结构化查询语言(SQL)与数据库通讯。WebSQL的野史充满了弯曲,但底线是一向不主流的浏览器厂商对WebSQL继续辅助。

万一WebSQL实际上是贰个丢掉的技巧,为啥还要提它呢?有趣的是,WebSQL在浏览器里获取巩固的支撑。Chrome,
Safari, iOS Safari, and
Android 浏览器都支持。别的,并不是那一个浏览器的新颖版本才提供支撑,许多那么些新式最好的浏览器之前的本子也得以支撑。有趣的是,即使你为WebSQL添加帮衬来支撑IndexedDB,你突然意识,许多浏览器厂商和版本成为帮助浏览器内置数据库的某种化身。

于是,借使你的应用程序真正需求贰个客户端数据库,你想要达到的最高级其他应用恐怕,当IndexedDB不可用时,大概你的应用程序只怕看起来要求采纳接纳WebSQL来帮衬客户端数据架构。即便文档数据库和关全面据库管理数据有分明的差别,但万一你有不错的悬空,就足以采纳当地数据库创设2个应用程序。

IndexedDB的差别之处在于,您能够创设有些项目数据的对象存储,然后只需将JavaScript对象留存在该存储中即可。每一个对象存储都可以有目录的汇集,那样就能拓展高效的询问和迭代。

IndexedDB是还是不是切合笔者的应用程序?

目前最根本的难题:“IndexedDB是还是不是切合本人的应用程序?“像以后同等,答案是一定的:“视意况而定。“首先当你打算在客户端保存数据时,你会考虑HTML5地点存储。本地存储拿到大规模浏览器的支撑,有相当便于使用的API。简单有其优势,但其劣势是力不从心支撑复杂的摸索策略,存储多量的多少,并提供工作襄助。

IndexedDB是二个数据库。所以,当您想为客户端做出决定,考虑你哪些在服务端采取1个持久化介质的数据库。你大概会问本人有个别题材来支持控制客户端数据库是还是不是适合你的应用程序,包涵:

若果您对中间的别样难题答问了“是的”,很有只怕,IndexedDB是您的应用程序的贰个很好的候选。

 

使用IndexedDB

明日,你曾经有机遇熟习了有的的完好概念,下一步是初阶落实基于IndexedDB的应用程序。第2个步骤需求统一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显得怎么删除3个职分,图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的单对象上。其它,数据库相关的代码在3个名为db的app子对象上。

本条模块的代码应用IIFE,通过传递window对象来保证模块的方便范围。使用use
strict确保那一个函数的代码函数是依据(javascript严俊格局)严苛编译规则。db对象作为与数据库交互的富有函数的首要容器。最终,window对象检查app的实例是还是不是留存,即使存在,模块使用当前实例,若是不存在,则创立2个新目标。一旦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事件在开辟请求达成前触发。那么些模块被装置为只利用2个object
store,所以名字直接定义在那边。最终,实例成员被创立,它用来保存一旦打开请求落成后的数据库当前实例。

接下去的操作是贯彻upgrade
needed事件的事件处理程序。在此间,检查当前object
store的名字来判断请求的object store名是或不是留存,假若不设有,创造object
store。

JavaScript

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

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

在那一个事件处理程序里,通过事件参数e.target.result来访问数据库。当前的object
store名称的列表在_db.objectStoreName的字符串数组上。以往,假若object
store不设有,它是通过传递object
store名称和store的键的概念(自增,关联到数码的ID成员)来创制。

模块的下二个功效是用来捕获错误,错误在模块不同的请求创建时冒泡。

JavaScript

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

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

在那里,errorHandler在一个警告框展现其余错误。那些函数是有意保持容易,对开发本身,当你学习运用IndexedDB,您可以很不难地看看其他错误(当她们发生时)。当您准备在生养条件使用那个模块,您须要在这几个函数中贯彻部分错误处理代码来和你的应用程序的上下文打交道。

距今基础完成了,这一节的其他部分将演示怎样完毕对数据库执行一定操作。第四个须求检查的函数是open函数。

JavaScript

open: function (callback) { var request = window.indexedDB.open(
db.objectStoreName, db.version); request.onerror = db.errorHandler;
request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) {
db.instance = request.result; db.instance.onerror = db.errorHandler;
callback(); }; },

1
2
3
4
5
6
7
8
9
10
11
12
open: function (callback) {
    var request = window.indexedDB.open(
        db.objectStoreName, db.version);
    request.onerror = db.errorHandler;
    request.onupgradeneeded = db.upgrade;
    request.onsuccess = function (e) {
        db.instance = request.result;
        db.instance.onerror =
            db.errorHandler;
        callback();
    };
},

open函数试图打开数据库,然后实施回调函数,告知数据库成功打开方可准备使用。通过拜访window.indexedDB调用open函数来创制打开请求。那么些函数接受你想打开的object
store的名称和你想利用的数据库版本号。

假定请求的实例可用,第①步要开展的做事是设置错误处理程序和升迁函数。记住,当数据库被打开时,若是脚本请求比浏览器里更高版本的数据库(可能只要数据库不设有),升级函数运营。可是,尽管请求的数据库版本匹配当前数据库版本同时没有不当,success事件触发。

设若全勤成功,打开数据库的实例可以从呼吁实例的result属性得到,那个实例也缓存到模块的实例属性。然后,onerror事件设置到模块的errorHandler,作为将来任何请求的一无所长捕捉处理程序。最终,回调被执行来告诉调用者,数据库已经打开并且正确地布局,可以动用了。

下三个要促成的函数是helper函数,它回到所请求的object store。

JavaScript

getObjectStore: function (mode) { var txn, store; mode = mode ||
‘readonly’; txn = db.instance.transaction( [db.objectStoreName],
mode); store = txn.objectStore( db.objectStoreName); return store; },

1
2
3
4
5
6
7
8
9
getObjectStore: function (mode) {
    var txn, store;
    mode = mode || ‘readonly’;
    txn = db.instance.transaction(
        [db.objectStoreName], mode);
    store = txn.objectStore(
        db.objectStoreName);
    return store;
},

在此间,getObjectStore接受mode参数,允许你决定store是以只读如故读写方式请求。对于这一个函数,暗许mode是只读的。

逐个针对object
store的操作都是在多少个事物的左右文中执行的。事务请求接受三个object
store名字的数组。那些函数这一次被布置为只行使二个object
store,然而假设您须求在作业中操作两个object store,你要求传递七个object
store的名字到数组中。事务函数的第二个参数是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的3个可写实例。然后,检查数据对象的ID成员是还是不是留存。固然存在ID值,数据必须创新,put函数被调用,它创造持久化请求。否则,借使ID不存在,那是新数据,add请求再次回到。最终,不管put或然add
请求是还是不是执行了,success事件处理程序必要设置在回调函数上,来告诉调用脚本,一切进展顺遂。

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

在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 收藏
评论

在 二〇〇八 年 十二月 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,那是八个万分重大的点子,那是代码中绝无仅有可以供你创立对象存储和目录的地点。

相关文章

发表评论

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

网站地图xml地图