zoukankan      html  css  js  c++  java
  • 初试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与之前不同时,才会触发.

  • 相关阅读:
    kubernetes进阶(一) kubectl工具使用详解
    二进制安装kubernetes(七) 部署知识点总结
    1024程序员节:这就是国内开发者的现状?
    php 伪协议
    浅谈 PHP 与手机 APP 开发(API 接口开发)
    比RBAC更好的权限认证方式(Auth类认证)
    PHP获得毫秒数
    2020年PHP面试题附答案(实战经验)
    分享几套2019年各大公司最新的PHP面试题,几斤几两一试便知
    PHP面试题2019年百度工程师面试题及答案解析
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/html5_localstorage.html
Copyright © 2011-2022 走看看