初试WebStorage之localstorage

今天小试一下html5中引入的localStorage特性(后来查了下localStorage应该是W3C中Web Storage的一部分,而不是Html5), 这个特性在IE8+中也已支持,其他的浏览器应该都已支持(像chrome, firefox一般都会自动升级到最新). 在学习的过程中也参考了一些文章,比如 Diveintohtml5系列html5demos系列 .总之网上的资源还是很多的.下面就拿出我比较简单的测试代码来 说明一下.

首先来段工具代码, 这段放在外部js中在中引入

 1 // 探测浏览器是否支持localStorage
 2 var isSupportLocalStorage = function() {
 3     try {
 4         return 'localStorage' in window && window['localStorage'] != null;
 5     } catch (e) {
 6         return false;
 7     }
 8 };
 9 
10 // 一段老生常谈的添加事件通用方法, 不过这样写更巧妙些
11 // addEvent会初始化为适合当前浏览器的方法
12 // 不用每次都判断, 而且对IE中eventHandler的调用做了小小的改进
13 // 让eventHandler的执行context为触发事件的元素
14 var addEvent = (function() {
15     if(document.addEventListener) {
16         return function(el, type, fn) {
17             if(el && el.nodeName || el === window) {
18                 el.addEventListener(type, fn, false);
19             } else if (el && el.length) {
20                 for(var i = 0; i < el.length; i++) {
21                     addEvent(el[i], type, fn);
22                 }
23             }
24         };
25     } else {
26         return function(el, type, fn) {
27             if(el && el.nodeName || el === window) {
28                 el.attachEvent('on' + type, function() {
29                     return fn.call(el, window.event);
30                 });
31             } else if (el && el.length) {
32                 for(var i = 0; i < el.length; i++) {
33                     addEvent(el[i], type, fn);
34                 }
35             }
36         };
37     }
38 })();

下面是配合测试的html代码, 测试一共两个页面A和B,访问方式是http://localhost:8080/FrontEnd/A.html(B.html), html部分都是相同的. 一个输入框,一个按钮

1 <input id="data" type="text" name="data" />
2 <button id="saveBtn">save</button>

下面来看页面A.html中的js代码

 1 if(isSupportLocalStorage()) {
 2     // 清除所有存储的key,value值
 3     // localStorage.clear();
 4     
 5     var dataInput = document.getElementById('data'),
 6         saveBtn = document.getElementById('saveBtn');
 7     
 8     addEvent(saveBtn, 'click', function () {
 9         // 按下按钮存下当前输入框中的值
10         localStorage.setItem('storage-event-test', dataInput.value);
11     }); 
12     
13     // 给window监听storage事件    
14     addEvent(window, 'storage', function (event) {
15         // 查看event对象内容
16         // console.dir(event);
17         // 输出oldValue和newValue 以作观察   
18         console.log('key: %s, old value: %s, new value: %s', event.key, event.oldValue, event.newValue);
19     });
20     
21     // 存储数字
22     localStorage.setItem('number', 1);
23     // 存储对象 因为localStorage最终都是以String来存储的  所以如果要存储对象 可以覆写它的toString方法
24     // 按照你想要的字符串格式来存储, 然后取出后再做相应的处理, 这里就拿json格式做个例子
25     localStorage.setItem('obj', "{'name':'Andrew', 'job': 'Developer'}");
26     // 常规的存储
27     localStorage.setItem('string', 'hello world');
28 
29 } else {
30     // 这里可以做些降级的方案, 当然也可以给出一个不支持的提示
31     var span = document.createElement("span");
32     span.style.color = 'red';
33     span.innerHTML = 'oops, your browser dones\'t support localStorage yet, :(';
34     document.getElementsByTagName('body')[0].appendChild(span);
35 }

再来看一下B.html中的js代码, 基本和A.html中的相同, 只是中间一段存储代码改成读取而已, 比较简单

 1 if(isSupportLocalStorage()) {
 2     //localStorage.clear();
 3     
 4     var dataInput = document.getElementById('data'),
 5         saveBtn = document.getElementById('saveBtn');
 6     
 7     addEvent(saveBtn, 'click', function () {
 8         localStorage.setItem('storage-event-test', dataInput.value);
 9     }); 
10     
11     // 给window监听storage事件
12     addEvent(window, 'storage', function (event) {
13         // 查看event对象内容
14         // console.dir(event);
15         // 输出oldValue和newValue 以作观察
16         console.log('key: %s, old value: %s, new value: %s', event.key, event.oldValue, event.newValue);
17     });
18     
19     // 取出来也是String类型的, 要用parseInt转换下
20     console.log(parseInt(localStorage.getItem('number')));
21     // 取出来的json格式字符串要用eval解析一下 转换成对象
22     console.dir(eval('(' + localStorage.getItem('obj') + ")"));
23     // 普通的读取
24     console.log(localStorage.getItem('string'));
25     
26 } else {
27     var span = document.createElement("span");
28     span.style.color = 'red';
29     span.innerHTML = 'oops, your browser dones\'t support localStorage yet, :(';
30     document.getElementsByTagName('body')[0].appendChild(span);
31 }

我先在firefox5中进行测试,一开始还遇到了一个可笑的问题, 没有通过启动本地的运用服务器来访问(以http://localhost:8080/...),直接是个静态页面(以file:///"形式), 在firebug下搞了半天也没看到window下的localStorage属性,而且storage事件也根本不触发.放到IE9中,F12开发者工具的调试输出面板中直接报个错, localStorage为null或未定义. 后来google了一下,在stackoverflow中找到了答案, localStorage要通过域名访问的方式才能起作用.总算能继续进行下去了: )

在firefox5中存储和读取都是正常的, 但是对storage事件的触发似乎有点问题, 自身页面进行setItem后没有触发window的storage事件, 但是同时访问A.html和B.html, 在A页面中进行 setItem能触发B页面中window的storage事件, 同样的在B页面中进行setItem能触发A页面中window的storage事件. 在IE9中, 页面自身的设值能触发当前页面的storage事件,同样当前页面的设值能触发同一 "起源" 下其他页面window的storage事件,这看起来似乎更让人想的通些.

关于"起源"这个词 Dev.Opera-WebStorage 中用的是origin. 我就姑且把origin翻译成蹩脚的"起源"吧, 文章最后关于web storage的注意点里有这么一句: Storage per origin:All storage from the same origin will share the same storage space 并且要 协议 + 域名 + 端口 一样才能算同一origin, 这个origin下的页面才能共享一个storage space. 有兴趣的可以去读下此文章.

还有firefox中跨页面触发,好像也有些让人不解. 我的测试结果是这样的(dataInput.value直接用字符串进行代替):

  • A中 setItem('storage-event-test', 'aaaa') -> B的console输出oldValue:     , newValue: aaaa
  • B中 setItem('storage-event-test', 'bbbb') -> A的console输出oldValue:     , newValue: bbbb
  • A中 setItem('storage-event-test', 'cccc') -> B的console输出oldValue: aaaa, newValue: cccc
  • B中 setItem('storage-event-test', 'dddd') -> A的console输出oldValue: bbbb, newValue: dddd

我所预期的结果是,两个页面应该共享同一个storageArea

  • A中 setItem('storage-event-test', 'aaaa') -> B的console输出oldValue:     , newValue: aaaa
  • B中 setItem('storage-event-test', 'bbbb') -> A的console输出oldValue: aaaa, newValue: bbbb
  • A中 setItem('storage-event-test', 'cccc') -> B的console输出oldValue: bbbb, newValue: cccc
  • B中 setItem('storage-event-test', 'dddd') -> A的console输出oldValue: cccc, newValue: dddd

这个结果一看就是不怎么对劲, 好像localStorage中的storageArea是各自独立的,而非对于同一个 "起源" 共享的.但是A页面中的那段存储在B页面中却能正常读取. 在IE9下结果是我所预期的那种. 所以搞到最后我就纳闷了难道是firefox的bug还是我对localStorage的理解还有出入, 如果有园友知道其中的缘由, 希望能留言指导一下, 先谢谢了.

在IE9里发现一个问题,相同的key,不管你value是否与之前一样,都会触发storage事件,而firefox中不会,只有当value与之前不同时,才会触发.

posted @ 2011-07-04 11:15  MrPrime  阅读(6173)  评论(0编辑  收藏  举报