HTML5项目笔记10:使用HTML5 IndexDB设计离线数据库

2019-03-28 14:41|来源: 网络

之前的文章()里面描述了HTML5 离线数据存储的Web SQL,一个基于SQLite 的离线数据库,不过W3C 的 WebDatabase 规范中说这份规范不再维护了,取而代之的是IndexDB,一个NoSQL类型的数据库。

 

Html5Rocks把他们的优缺点做了比对,IndexDB综合看来有如下优点:

允许快速索引和搜索的对象,所以在HTML5 的 web应用程序中, 你可以有效管理你的数据和高效率的读/写操作。

W3C主推的离线数据库类型,逐渐替代Web SQL类型数据库,更新效率高并不断完善。

工作在异步模式下执行每步操作。让你使用高效率的的JavaScript事件驱动模块

 

现在我们来尝试使用这个IndexDB:

1、初始化声明

1             var dbName = "H5AppDB"; //数据库名称
2             var dbVersion = 2.0; //数据库版本
3             var tablename = "todo"; //表名
View Code

 

2、初始并实例化IndexDB数据上下文 

 1  //定义一个IndexDB方法集合对象
 2             var H5AppDB = {};
 3 
 4             //实例化IndexDB数据上下文,这边根据浏览器类型来做选择
 5             var indexedDB = window.indexedDB || window.webkitIndexedDB ||window.mozIndexedDB;
 6 
 7             if ('webkitIndexedDB' in window) {
 8                 window.IDBTransaction = window.webkitIDBTransaction;
 9                 window.IDBKeyRange = window.webkitIDBKeyRange;
10             }
11 
12             H5AppDB.indexedDB = {};
13             H5AppDB.indexedDB.db = null;
14 
15             //错误信息,打印日志
16             H5AppDB.indexedDB.onerror = function (e) {
17                 log.debug(e);
18             };
View Code

 

3、打开数据库,初始化数据库,并创建存储对象

 1   H5AppDB.indexedDB.open = function () {
 2               
 3                 //初始IndexDB
 4                 var request = indexedDB.open(dbName, dbVersion);
 5 
 6                 request.onsuccess = function (e) {
 7                     // Old api: var v = "2-beta"; 
 8                     log.debug("success to open DB: " + dbName);
 9                     H5AppDB.indexedDB.db = e.target.result;
10                     var db = H5AppDB.indexedDB.db;
11                     if (db.setVersion) {
12                         console.log("in old setVersion: " + db.setVersion);
13                         if (db.version != dbVersion) {
14                             var req = db.setVersion(dbVersion);
15                             req.onsuccess = function () {
16                                 if (db.objectStoreNames.contains(tablename)) {
17                                     db.deleteObjectStore(tablename);
18                                 }
19                                 var store = db.createObjectStore(tablename, { keyPath: "timeStamp" });//keyPath:主键,唯一性
20 
21                                 var trans = req.result;
22                                 trans.oncomplete = function (e) {
23                                     console.log("== trans oncomplete ==");
24                                     H5AppDB.indexedDB.getAllTodoItems();
25                                 }
26                             };
27                         }
28                         else {
29                            H5AppDB.indexedDB.getAllTodoItems();
30                         }
31                     }
32                     else {
33                        H5AppDB.indexedDB.getAllTodoItems();
34                     }
35                 }
36 
37                 //如果版本不一致,执行版本升级的操作
38                 request.onupgradeneeded = function (e) {
39                     log.debug("going to upgrade our DB!");
40 
41                     H5AppDB.indexedDB.db = e.target.result;
42                     var db = H5AppDB.indexedDB.db;
43                     if (db.objectStoreNames.contains(tablename)) {
44                         db.deleteObjectStore(tablename);
45                     }
46 
47                     var store = db.createObjectStore(tablename, { keyPath: "timeStamp" });//NoSQL类型数据库中必须的主键,唯一性
48 
49                     H5AppDB.indexedDB.getAllTodoItems();
50                 }
51 
52                 request.onfailure = H5AppDB.indexedDB.onerror;
53             };
View Code

 

4、获取对象信息,并进行轮询读取,然后绑定到页面

 1   //、获取对象信息
 2             H5AppDB.indexedDB.getAllTodoItems = function () {
 3 
 4                 var todos = document.getElementById("todoItems");
 5                 todos.innerHTML = "";
 6 
 7 
 8 
 9                 var db = H5AppDB.indexedDB.db;
10                 var trans = db.transaction([tablename], "readwrite");//通过事物开启对象
11                 var store = trans.objectStore(tablename);//获取到对象的值
12 
13                 // Get everything in the store;
14 
15                 var keyRange = IDBKeyRange.lowerBound(0);
16                 var cursorRequest = store.openCursor(keyRange);//开启索引为0的表
17 
18                 cursorRequest.onsuccess = function (e) {
19 
20                     var result = e.target.result;
21 
22                     if (!!result == false)
23                         return;
24 
25                     renderTodo(result.value);
26                     result.continue();//这边执行轮询读取
27                 };
28 
29                 cursorRequest.onerror = H5AppDB.indexedDB.onerror;
30             };
31 
32             //绑定数据
33             function renderTodo(row) {
34                var todos = document.getElementById("todoItems");
35                var li = document.createElement("li");
36                var a = document.createElement("a");
37                var t = document.createTextNode(row.text);
38 
39               a.addEventListener("click", function() {
40                 H5AppDB.indexedDB.deleteTodo(row.timeStamp);
41               }, false);
42 
43         a.textContent = " [Delete]";
44         li.appendChild(t);
45         li.appendChild(a);
46         todos.appendChild(li);
47     };
View Code

 效果如下:

 

5、添加数据对象

 1             //4、添加数据对象
 2             H5AppDB.indexedDB.addTodo = function (todoText) {
 3                 var db = H5AppDB.indexedDB.db;
 4                 var trans = db.transaction([tablename], "readwrite");
 5                 var store = trans.objectStore(tablename);
 6 
 7                 var newArray = new Array("wzh","374532");
 8 
 9                 //数据以对象形式保存,体现NoSQL类型数据库的灵活性
10                 var data = {
11                     "text": todoText,
12                     "timeStamp": new Date().getTime(),
13                     "obj":newArray                         
14                 };
15 
16                 var request = store.put(data);//保存数据
17 
18                 request.onsuccess = function (e) {
19                     H5AppDB.indexedDB.getAllTodoItems();
20                 };
21 
22                 request.onerror = function (e) {
23                     log.debug("Error Adding: ", e);
24                 };
25             };            
26             function addTodo() {
27                 var todo = document.getElementById("todo");
28                 H5AppDB.indexedDB.addTodo(todo.value);
29                 todo.value = "";
30             }
View Code

 可以随意添加BJson格式的对象,体现NoSQl类型数据库的优越性...

 

6、删除数据对象(根据主键删除)

 1             
 2             // 删除数据对象
 3             H5AppDB.indexedDB.deleteTodo = function(id) {
 4               var db = H5AppDB.indexedDB.db;
 5               var trans = db.transaction([tablename], "readwrite");
 6               var store = trans.objectStore(tablename);
 7 
 8               var request = store.delete(id);//根据主键来删除
 9 
10               request.onsuccess = function(e) {
11                 
12                  H5AppDB.indexedDB.getAllTodoItems();
13                   alert("删除成功");
14               };
15 
16              request.onerror = function(e) {
17                  log.debug("Error Adding: ", e);
18              };
19       };
View Code

 

W3C已经停止了对Web SQL  的更新,会更加完善对Index的规范草案和标准,所以以后的HTML5应用,有用到离线端数据库这一块,建议优先考虑IndexDB...

 

本文源码

相关问答

更多
  • 您好, 我的建议是,如果你想增加自己的入选机会,那最好还是花点钱制作一份专业的简历。相较于你将来可能得到的巨大收获,这真的只是一个小小的投资。 2.研究面试官 当我联系程序员来面试的时候,我总是会事先发电子邮件给他,并附上我的名字和博客地址。但是让我惊讶的是,当我给他面试的时候,他竟然对我还是一无所知。 再举个正面的例子,我在面试时也碰到过这类开发人员,甚至能对我以前写的一篇博客或者做的教学视频上面的内容侃侃而谈。 你说我会推荐哪个? 面试官也是人,也会有人性的弱点和特点。Dale Carnegie曾说过, ...
  • 在HTML5中有几种脱机存储的可能性:Web存储Web SQL数据库IndexedDB文件系统API 这里有所有这些选项的非常好的介绍: http://www.html5rocks.com/en/tutorials/offline/whats-offline/#toc-older-storage 与较早的选项(Cookie,基于插件的存储,浏览器特定功能)相比,我将引用以下文章: “新开发的存储API,我们称之为”HTML5存储“,在开放性和标准合规性方面一般都很优秀,当然,并非所有的浏览器都包含所有新的A ...
  • 我建议您查看Dive Into HTML 5,并决定如果您认为权衡是可以接受的。 据我所知,使用HTML 5没有负面的SEO含义。我刚刚运行w3c验证器在Dive Into HTML 5 ,它自动检测到它是HTML 5并验证它,所以我不认为也将是一个关注。 I'd recommend checking out Dive Into HTML 5 and deciding for yourself if you think the tradeoffs are acceptable. So far as I've ...
  • 馊主意。 访问机器的人总是能够读取本地存储器,没有什么可以做的,以防止它。 只需在firebug控制台中键入“localStorage”,就可以很好地列出所有的键/值对。 如果您的应用程序中存在XSS漏洞,那么存储在localStorage任何内容都可用于攻击者。 你可以尝试加密它,但是有一个catch。 在客户端上加密它是可能的,但这意味着用户必须提供密码, 并且必须依赖于经过验证的未经验证的加密技术的JavaScript实现。 当然可以在服务器端进行加密,但客户端代码无法读取或更新它,因此您将local ...
  • 也许尝试localstorage任何IPad应该支持它。 http://diveintohtml5.ep.io/storage.html 用户不应该丢失数据,除非他们清除浏览器缓存或您作为程序员覆盖它。 它由域存储。 Maybe try localstorage any IPad should support it. http://diveintohtml5.ep.io/storage.html The user should never lose the data unless they clear br ...
  • 你不能使用WebSQL吗? (请参阅问题iPad上的iOS(Safari)中Web SQL DB的最大大小是多少?LocalStorage怎么样? )。 如果您为LocalStorage编码它,您可以轻松地使用LocalStorage API访问iOS设备上的WebSQL ... 也许跳到PhoneGap会解决你的一些问题? 您是否需要存储数据库中的所有数据? 我有一个用于进行Syncrhonization的库,它目前是LocalStorage,但下一次更新将允许我使用几乎任何存储机制,因为它只需要一个索引 ...
  • 仅适合路过的人,不是优雅的解决方案,而是至少一个。 您可以将Adobe动画保存为动画视频('mov'文件),并使用Adobe Media Converter或您喜欢的任何其他程序优化其大小和格式。 在这种情况下我用mp4转换它。 注意:发布视频时,如果有音轨,只有从动画的第二帧开始,它才会包含在视频中。 发现它有点棘手,值得一提。 只要你有一个'mp4'文件,就把它添加到你的应用资产中,你可以用经典的html方式将它包含在Ionic页面中。 就我而言,这是一个全屏播放的视频,所以这是我的代码:
  • Chrome和Safari都有数据库GUI和命令行界面。 正如您所发现的,它们位于Developer Tools的“Resources> Databases”选项卡下(在Safari中称为Web Inspector)。 两者都非常相似,因为两种浏览器都基于Webkit。 您可以通过选择数据库的名称来获取临时查询的命令行界面。 在能够查看数据库之前,您必须在控制台或代码中调用openDatabase() 。 该数据库基于SQLite,因此您可以使用SQLite在此接受的几乎所有命令,除了帮助程序命令,例如'. ...
  • 通过搜索任何HTML文档,我无法找到任何关于硬大小限制或任何大小限制的指示。 我相信Safari在iPhone / iPad的应用程序存储上有5MB的上限( 你曾经提到使用iPad。 ) 这是关于脱机Web应用程序/缓存的HTML标准 这是一个很好的链接,涉及使用HTML5实现离线缓存 - 它还有几个良好的链接到底部。 希望这可以帮助你! I haven't been able to find anything regarding a hard size limitation or any indicati ...
  • 不,jQuery不是必需的。 毕竟,简单地说HTML5样板,样板/模板,可以改变。 如果您不需要jQuery,可以通过删除以下两行来删除它: