做項目時需要用H5本地存儲,感覺還不錯 下面是一些基礎知識和一個完整的實例
HTML5 的一個重要特性是本地數據持久性,它使用戶能夠在線和離線訪問 Web 應用程序。此外,本地數據持久性使移動應用程序更靈敏,使用的帶寬更少,而且能夠在低帶寬場景中更高效地工作。HTML5 提供了一些本地數據持久性選項。第一個選項是 localstorage,它支持您使用一個簡單的鍵值對來存儲數據。IndexedDB(一個更加強大的選項)支持您本地存儲大量對象,並使用健壯的數據訪問機制檢索數據。
IndexedDB API 取代了 Web Storage API,后者在 HTML5 規范中已不推薦使用。(但一些領先的瀏覽器仍然支持 Web Storage,其中包括蘋果公司的 Safari 和 Opera Web 瀏覽器)與 Web Storage 相比,IndexedDB 具有多個優勢,其中包括索引、事務處理和健壯的查詢功能。本文將通過一系列的示例來展示如何管理 IndexedDB 數據庫。
重要概念
一個網站可能有一個或多個 IndexedDB 數據庫,每個數據庫必須具有惟一的名稱。
一個數據庫可包含一個或多個對象存儲。一個對象存儲(由一個名稱惟一標識)是一個記錄集合。每個記錄有一個鍵 和一個值。該值是一個對象,可擁有一個或多個屬性。鍵可能基於某個鍵生成器,從一個鍵路徑衍生出來,或者是顯式設置。一個鍵生成器自動生成惟一的連續正整數。鍵路徑定義了鍵值的路徑。它可以是單個 JavaScript 標識符或多個由句點分隔的標識符。
規范中包含一個異步 API 和一個同步 API。同步 API 用於 Web 瀏覽器中。異步 API 使用請求和回調。
在以下示例中,輸出附加到一個具有 ID result 的 div 標記上。要更新 result 元素,可在每個數據操作期間清除並設置 innerHTML 屬性。每個示例 JavaScript 函數由 HTML 按鈕的一個 onclick 事件調用。
object store
有了數據庫后我們自然希望創建一個表用來存儲數據,但indexedDB中沒有表的概念,而是objectStore,一個數據庫中可以包含多個objectStore,objectStore是一個靈活的數據結構,可以存放多種類型數據。也就是說一個objectStore相當於一張表,里面存儲的每條數據和一個鍵相關聯。
我們可以使用每條記錄中的某個指定字段作為鍵值(keyPath),也可以使用自動生成的遞增數字作為鍵值(keyGenerator),也可以不指定。選擇鍵的類型不同,objectStore可以存儲的數據結構也有差異
事務
在對新數據庫做任何事情之前,需要開始一個事務。事務中需要指定該事務跨越哪些object store。
事務具有三種模式
- 只讀:read,不能修改數據庫數據,可以並發執行
- 讀寫:readwrite,可以進行讀寫操作
- 版本變更:verionchange
當用戶訪問你的網站時,如果用戶的瀏覽器支持IndexedDB,則首先觸發的是upgradeneeded事件
完整示例
<!doctype html> <html> <head> </head> <body> <script> var db; //檢測瀏覽器是否支持 indexedDBOk function indexedDBOk() { return "indexedDB" in window; } document.addEventListener("DOMContentLoaded", function() { //判斷 indexedDBOk 支持 是/否? if(!indexedDBOk) return; //打開數據庫 這個變量其中一個屬性是一個已存在的對象存儲list,名為objectStoreNames var openRequest = indexedDB.open("idarticle_people6",1); openRequest.onupgradeneeded = function(e) { var thisDB = e.target.result; //通過contains方法檢車某個對象是否已經存在了,如果不存在則可進行創建 if(!thisDB.objectStoreNames.contains("people")) { //使用key生成器 var os = thisDB.createObjectStore("people", {autoIncrement:true}); //索引 //os.createIndex(索引名稱,列,指定某個列是否是唯一) os.createIndex("name", "name", {unique:false}); //I want email to be unique os.createIndex("email", "email", {unique:true}); } } openRequest.onsuccess = function(e) { db = e.target.result; //監聽添加事件 document.querySelector("#addButton").addEventListener("click", addPerson, false); document.querySelector("#getButton").addEventListener("click", getPeople, false); document.querySelector("#delete").addEventListener("click", deleteData, false); document.querySelector("#getStore").addEventListener("click", getDataByKey, false); document.querySelector("#getButton1").addEventListener("click", getDataByKey1, false); document.querySelector("#getButton2").addEventListener("click", getDataByKey2, false); } openRequest.onerror = function(e) { //Do something for the error } },false); function addPerson(e) { var name = document.querySelector("#name").value; var email = document.querySelector("#email").value; console.log("About to add "+name+"/"+email); // 對象 = db.事物(將要處理的數組,事物類型) var transaction = db.transaction(["people"],"readwrite"); //設置存儲對象people為為讀寫操作,然后使用objectStore指定要操作的存儲對象,存在變量store var store = transaction.objectStore("people"); //設置添加數據 var person = { name:name, email:email, created:new Date() } //聲明一個普通的javascript對象,使用store的add方法 增加這個對象到對象存儲中 var request = store.add(person); //增加數據是異步操作,增加兩個事件監聽 request.onerror = function(e) { alert("Sorry, that email address already exists."); console.log("Error",e.target.error.name); console.dir(e.target); //some type of error handler } request.onsuccess = function(e) { console.log("Woot! Did it"); } } function getPeople(e) { var name = document.querySelector("#nameSearch").value; var endname = document.querySelector("#nameSearchEnd").value; if(name == "" && endname == "") return; // 對象 = db.事物(將要處理的數組,事物類型) var transaction = db.transaction(["people"],"readonly"); //設置存儲對象people為為讀寫操作,然后使用objectStore指定要操作的存儲對象,存在變量store var store = transaction.objectStore("people"); var index = store.index("name"); //Make the range depending on what type we are doing var range; if(name != "" && endname != "") { range = IDBKeyRange.bound(name, endname); } else if(name == "") { range = IDBKeyRange.upperBound(endname); } else { range = IDBKeyRange.lowerBound(name); } var s = ""; index.openCursor(range).onsuccess = function(e) { var cursor = e.target.result; if(cursor) { s += "<h2>Key "+cursor.key+"</h2><p>"; for(var field in cursor.value) { s+= field+"="+cursor.value[field]+"<br/>"; } s+="</p>"; cursor.continue(); } document.querySelector("#status").innerHTML = s; } } //清空store function deleteData(e) { var transaction = db.transaction(["people"],"readwrite"); var store=transaction.objectStore("people"); store.clear(); } //列表查詢 function getDataByKey(e) { var s = ""; db.transaction(["people"], "readonly").objectStore("people").openCursor().onsuccess = function(e) { var cursor = e.target.result; if(cursor) { s += "<h2>Key "+cursor.key+"</h2><p>"; for(var field in cursor.value) { s+= field+"="+cursor.value[field]+"<br/>"; } s+="</p>"; cursor.continue(); } document.querySelector("#status2").innerHTML = s; } } //查詢 function getDataByKey1(){ var name = document.querySelector("#nameSearch1").value; if(name === "" ) return; var transaction = db.transaction(["people"],"readonly"); var store = transaction.objectStore("people"); var index = store.index("name"); var request = index.get(name); request.onsuccess=function(e){ var result = e.target.result; console.log(result.email); }; } //更新 function getDataByKey2(e){ var name = document.querySelector("#nameSearch2").value; if(name === "" ) return; var transaction = db.transaction(["people"],"readwrite"); var store=transaction.objectStore("people"); var index = store.index("name"); var request=index.get(name); request.onsuccess=function(e){ var result = e.target.result; result.email=909; store.put(result); }; } </script> <input type="text" id="name" placeholder="Name"><br/> <input type="email" id="email" placeholder="Email"><br/> <button id="addButton">Add Data</button> <p/> Starting with: <input type="text" id="nameSearch" placeholder="Name"><br/> Ending with: <input type="text" id="nameSearchEnd" placeholder="Name"><br/> <button id="getButton">Get By Name Range</button> <p/> <p> <button id="delete">delete clear</button> </p> <p> <button id="getStore">查找數據(列)</button> </p> <p id="status2"> </p> <p/> <input type="text" id="nameSearch1" placeholder="Name"><br/> <button id="getButton1">查找數據</button> <p/> <p/> <input type="text" id="nameSearch2" placeholder="Name"><br/> <button id="getButton2">更新數據</button> <p/> <div id="status"></div> </body> </html>
