以前的文章(http://www.cnblogs.com/wzh2010/archive/2012/05/22/2514017.html)裏面描述了HTML5 離線數據存儲的Web SQL,一個基於SQLite 的離線數據庫,不過W3C 的 WebDatabase 規範中說這份規範再也不維護了,取而代之的是IndexDB,一個NoSQL類型的數據庫。html
Html5Rocks把他們的優缺點作了比對,IndexDB綜合看來有以下優勢:web
容許快速索引和搜索的對象,因此在HTML5 的 web應用程序中, 你能夠有效管理你的數據和高效率的讀/寫操做。數據庫
W3C主推的離線數據庫類型,逐漸替代Web SQL類型數據庫,更新效率高並不斷完善。api
工做在異步模式下執行每步操做。讓你使用高效率的的JavaScript事件驅動模塊瀏覽器
如今咱們來嘗試使用這個IndexDB:app
一、初始化聲明異步
1 var dbName = "H5AppDB"; //數據庫名稱 2 var dbVersion = 2.0; //數據庫版本 3 var tablename = "todo"; //表名
二、初始並實例化IndexDB數據上下文 ide
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 };
三、打開數據庫,初始化數據庫,並建立存儲對象spa
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 };
四、獲取對象信息,並進行輪詢讀取,而後綁定到頁面debug
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 };
效果以下:
五、添加數據對象
1 //四、添加數據對象 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 }
能夠隨意添加BJson格式的對象,體現NoSQl類型數據庫的優越性...
六、刪除數據對象(根據主鍵刪除)
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 };
W3C已經中止了對Web SQL 的更新,會更加完善對Index的規範草案和標準,因此之後的HTML5應用,有用到離線端數據庫這一塊,建議優先考慮IndexDB...