分析
H5本地存儲有兩個API,一個是Web Storage,還有一個是Web SQL。無論是哪個,都是基於JavaScript語言來使用,而Web Storage提供了兩種存儲類型 API: sessionStorage 和 localStorage,兩者的差別主要是數據的保存時長及數據的共享方式。javascript
那麼,如何監測本地存儲webstorage的數據是否改變呢?html
在H5中,window對象裏面有一個storage事件,咱們能夠進行監聽或者指定其事件處理函數的方法,在其餘頁面修改了sessionstorage或者localstorage中的值時,就會觸發註冊了storage事件。java
咱們先看一下幾個屬性:web
一、event.key 屬性:屬性值爲在 session 或 localStorage 中被修改的數據鍵值。移動web開發
二、event.oldValue 屬性:屬性值爲在 sessionStorage 或 localStorage 中被修改的值。瀏覽器
三、event.newValue 屬性:屬性值爲在 sessionStorage 或 localStorage 中被修改後的值session
四、event.url 屬性:屬性值爲修改 sessionStorage 或 localStorage 中值的頁面的URL地址app
五、event.storageArea 屬性 : 屬性值爲被變更的 sessionStorage 對象或 localStorage 對象函數
引用《h5移動web開發指南》上的話:this
「當同源頁面的某個頁面修改了localStorage,其他的同源頁面只要註冊了storage事件,就會觸發」
因此,localStorage
的例子運行須要以下條件:
- 同一瀏覽器打開了兩個同源頁面
- 其中一個網頁修改了
localStorage
- 另外一網頁註冊了
storage
事件
很容易犯的錯誤是,在同一個網頁修改本地存儲,又在同一個網頁監聽,這樣是沒有效果的。
例子
接下來咱們經過兩個例子來體驗一下。
實時監聽的頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>利用storage事件實時監視Web Storage中的數據</title> </head> <body> <script type="text/javascript"> //利用storage事件實時監視wev Storage中的數據 window.addEventListener('storage',function (e) {//e只是一個傳參 //獲取被修改的鍵值 if (e.key == 'test') { //獲取將要被添加內容的元素 var output = document.getElementById('output'); //將獲取到的修改值在元素中輸出 output.innerHTML = '原有值:' + e.oldValue; output.innerHTML += '<br />新值:' + e.newValue; output.innerHTML += '<br />變更頁面地址:' + utf8_decode(unescape(e.url)); //分別打印會發現內容一致 console.log(e.storageArea); console.log(localStorage); //此行代碼只在Chrome瀏覽器中有效 console.log(e.storageArea === localStorage);//輸出true } },false); function utf8_decode (utftext) { var string = ''; var i = c = c1 = c2 = 0; //獲取URL全部字符 while (i < utftext.length) { //獲取URL並將URL中全部 Unicode 編碼獲取 c = utftext.charCodeAt(i); //對 Unicode 編碼進行處理轉化成字符串 if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c < 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } </script> <output id="output"></output> </body> </html>
修改localStorage中數據的頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用於修改localStorage 中數據的頁面的代碼</title> </head> <body> <script type="text/javascript"> function setLOcalStorage () { //設置test鍵值下的內容等於input框中的內容 localStorage.test = document.getElementById('text1').value; } </script> 請輸入一些值:<input type="text" id="text1" /> <button onclick="setLOcalStorage()">設置</button> </body> </html>
實際效果:
代碼中用到的函數:
charCodeAt() 可返回指定位置的字符的 Unicode 編碼。這個返回值是 0 - 65535 之間的整數。 fromCharCode() 可接受一個指定的 Unicode 值,而後返回一個字符串。 unescape() 可對經過 escape() 編碼的字符串進行解碼。
下面是關於Unicode碼的一些註解:
Unicode只有一個字符集,中、日、韓的三種文字佔用了Unicode中0x3000到0x9FFF的部分
Unicode目前廣泛採用的是UCS-2,它用兩個字節來編碼一個字符, 好比漢字」經」的編碼是
0x7ECF,注意字符碼通常用十六進制來 表示,爲了與十進制區分,十六進制以0x開頭,0x7ECF
轉換成十進制 就是32463,UCS-2用兩個字節來編碼字符,兩個字節就是16位二進制, 2的16
次方等於65536,因此UCS-2最多能編碼65536個字符。 編碼從0到127的字符與ASCII編碼的
字符同樣,好比字母」a」的Unicode 編碼是0x0061,十進制是97,而」a」的ASCII編碼是0x61,
十進制也是97, 對於漢字的編碼,事實上Unicode對漢字支持不怎麼好,這也是沒辦法的, 簡
體和繁體總共有六七萬個漢字,而UCS-2最多能表示65536個,才六萬 多個,因此Unicode只
能排除一些幾乎不用的漢字,好在經常使用的簡體漢字 也不過七千多個,爲了能表示全部漢字,
Unicode也有UCS-4規範,就是用 4個字節來編碼字符
擴展
若是非得要在同一網頁監聽怎麼辦?能夠重寫localStorage的方法,拋出自定義事件:
<script> var orignalSetItem = localStorage.setItem; localStorage.setItem = function(key,newValue){ var setItemEvent = new Event("setItemEvent"); setItemEvent.key = key; setItemEvent.newValue = newValue; setItemEvent.oldValue = localStorage.getItem(key); window.dispatchEvent(setItemEvent); orignalSetItem.apply(this,arguments); } window.addEventListener("setItemEvent", function (e) { console.log('key: '+e.key); console.log('newValue: '+e.newValue); console.log('oldValue: '+e.oldValue); }); localStorage.setItem("nm","1234"); </script>