Web存儲允許我們在瀏覽器里保存簡單的鍵/值數據。Web存儲和cookie很相似,但它有著更好的實現方式,能保存的數據量也很大。這兩種類型共用相同的機制,但是被保存數據的可見性和壽命存在區別。 PS:還有一種存儲規範名為“索引資料庫API”(Indexed Database API),它允許保存富格 ...
Web存儲允許我們在瀏覽器里保存簡單的鍵/值數據。Web存儲和cookie很相似,但它有著更好的實現方式,能保存的數據量也很大。這兩種類型共用相同的機制,但是被保存數據的可見性和壽命存在區別。
PS:還有一種存儲規範名為“索引資料庫API”(Indexed Database API),它允許保存富格式數據和進行SQL風格的查詢。
1.使用本地存儲
我們可以通過全局屬性 localStorage訪問本地存儲功能。這個屬性會返回一個Storage 對象,下表對其進行了介紹。Storage 對象被用來保存鍵/值形式的字元串對。
Storage 對象可用來存儲鍵/值對,其中鍵和值都是字元串。鍵必須是惟一的,這就意味著如果我們用 Storage對象里已經存在的鍵調用setItem方法,就會更新它的值。下麵的示例展示瞭如何添加、修改和清除本地存儲中數據。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用本地存儲</title> <style> body > * {float: left;} table {border-collapse: collapse;margin-left:50px; } th,td {padding: 4px;} th {text-align: right;} input {border: thin solid black;padding: 2px;} label {min-width: 50px;display: inline-block;text-align: right;} #countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;} </style> </head> <body> <div> <div><label>Key:</label><input id="key" placeholder="Enter Key" /></div> <div><label>Value:</label><input id="value" placeholder="Enter Value" /></div> <div id="buttons"> <button id="add">Add</button> <button id="clear">Clear</button> </div> <p id="countmsg">These are <span id="count"></span> items </p> </div> <table id="data" border="1"> <tr><th>Item Count:</th><td id="count">-</td> </tr> </table> <script> displayData(); var buttons = document.getElementsByTagName("button"); for(var i=0;i<buttons.length;i++){ buttons[i].onclick = handleButtonPress; } function handleButtonPress(e){ switch (e.target.id){ case 'add': var key = document.getElementById("key").value; var value = document.getElementById("value").value; localStorage.setItem(key,value); displayData(); break; case 'clear': localStorage.clear(); displayData(); break; } } function displayData(){ var tableElem = document.getElementById("data"); tableElem.innerHTML = ""; var itemCount = localStorage.length; document.getElementById("count").innerHTML = itemCount; for(var i=0;i<itemCount;i++){ var key = localStorage.key(i); var val = localStorage[key]; tableElem.innerHTML += "<tr><th>" + key + ":</th><td>" + val + "</td></tr>"; } } </script> </body> </html>
此例報告了本地存儲中的項目數量,並枚舉已保存的鍵/值對來填充一個表格元素。這裡添加了兩個button元素,在Add按鈕被按下時將他們的內容保存為項目。在響應Clear按鈕時,會清除本地存儲中的內容。其顯示效果如下:
瀏覽器不會刪除我們用 localStorage對象添加的數據,除非用戶自己清除瀏覽數據。
監聽存儲事件
通過本地存儲功能保存的數據對所有來源相同的文檔都是可用的。某個文檔對本地存儲進行修改時會觸發storage事件,我們可以監聽其他同源文檔上的這個事件來確保我們能跟上最新的變化。
與storage事件同時指派的對象是一個StorageEvent對象,它的成員如下表所示:
下麵的示例展示了一個文檔,它會監聽並編錄本地存儲對象上觸發的事件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>編錄本地存儲事件</title> <style> table {border-collapse:collapse; } th,td {padding: 4px;} </style> </head> <body> <table id="data" border="1"> <tr> <th>key</th> <th>oldValue</th> <th>newValue</th> <th>url</th> <th>storageArea</th> </tr> </table> <script> var tableElem = document.getElementById("data"); window.onstorage = handleStorage; function handleStorage(e){ var row = "<tr>"; row += "<td>" + e.key + "</td>"; row += "<td>" + e.oldValue + "</td>"; row += "<td>" + e.newValue + "</td>"; row += "<td>" + e.url + "</td>"; row += "<td>" + (e.storageArea == localStorage) + "</td>"; row += "</tr>"; tableElem.innerHTML += row; } </script> </body> </html>
storage事件是通過Window對象觸發的,此對象可以來自共用被改動存儲的任何一個文檔。此例中,每次接收到事件時都會給table元素添加一個新行,演示效果如下:
圖中的事件展示了給本地存儲添加新項目的過程。url屬性能幫助我們瞭解是哪個文檔觸發了變化。storageArea屬性會返回發生變化的Storage對象,它可以是本地或會話存儲對象。此例只接收來自本地存儲對象的事件。
PS:這些事件不會再製造變化的文檔內指派。
2. 使用會話存儲
會話存儲(session storage)的工作方式和本地存儲很接近,不同之處在於數據是各個瀏覽上下文私有的,會在文檔被關閉時移除。我們通過全局變數 sessionStorage訪問會話存儲,它會返回一個Storage對象。下麵的例子展示了會話存儲的用法:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用會話存儲</title> <style> body > * {float: left;} table {border-collapse: collapse;margin-left:50px; } th,td {padding: 4px;} th {text-align: right;} input {border: thin solid black;padding: 2px;} label {min-width: 50px;display: inline-block;text-align: right;} #countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;} </style> </head> <body> <div> <div><label>Key:</label><input id="key" placeholder="Enter Key" /></div> <div><label>Value:</label><input id="value" placeholder="Enter Value" /></div> <div id="buttons"> <button id="add">Add</button> <button id="clear">Clear</button> </div> <p id="countmsg">These are <span id="count"></span> items </p> </div> <table id="data" border="1"> <tr><th>Item Count:</th><td id="count">-</td> </tr> </table> <script> displayData(); var buttons = document.getElementsByTagName("button"); for(var i=0;i<buttons.length;i++){ buttons[i].onclick = handleButtonPress; } function handleButtonPress(e){ switch (e.target.id){ case 'add': var key = document.getElementById("key").value; var value = document.getElementById("value").value; sessionStorage.setItem(key,value); displayData(); break; case 'clear': sessionStorage.clear(); displayData(); break; } } function displayData(){ var tableElem = document.getElementById("data"); tableElem.innerHTML = ""; var itemCount = sessionStorage.length; document.getElementById("count").innerHTML = itemCount; for(var i=0;i<itemCount;i++){ var key = sessionStorage.key(i); var val = sessionStorage[key]; tableElem.innerHTML += "<tr><th>" + key + ":</th><td>" + val + "</td></tr>"; } } </script> </body> </html>
此例的工作方式和前面本地存儲的例子很接近,不同之處在於可見性和壽命受到限制。這些限制會影響storage事件的處理方式:前面提到的storage事件只會在共用存儲的文檔中觸發。對於會話存儲,這就意味著事件只會在內嵌文檔中觸發,比如 iframe里的文檔。修改前一示例如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用會話存儲的storage事件</title> <style> body > * {float: left;} table {border-collapse: collapse;margin-left:50px; } th,td {padding: 4px;} th {text-align: right;} input {border: thin solid black;padding: 2px;} label {min-width: 50px;display: inline-block;text-align: right;} #countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;} iframe {clear: left;} </style> </head> <body> <div> <div><label>Key:</label><input id="key" placeholder="Enter Key" /></div> <div><label>Value:</label><input id="value" placeholder="Enter Value" /></div> <div id="buttons"> <button id="add">Add</button> <button id="clear">Clear</button> </div> <p id="countmsg">These are <span id="count"></span> items </p> </div> <table id="data" border="1"> <tr><th>Item Count:</th><td id="count">-</td> </tr> </table> <br /> <iframe src="storage-02.html" width="666" height="222"><