• 基于localStorage和UserData的demo


    这两天系统学习了  localStorage和UserData,本文前半部分是一些网络上关于这方面的流行 的博文,用于备忘。 后半部分是两个自己做过的demo和封装好的兼容ie的api。

     

    本地存储解决方案很多,比如Flash SharedObjectGoogle GearsCookieDOM StorageUser Datawindow.nameSilverlightOpen Database等。

    Cookie web中得到广泛应用,但局限性非常明显,容量太小,有些站点会因为出于安全的考虑而禁用cookiecookie没有想象中的那么安全,Cookie 的内容会随着页面请求一并发往服务器。

    Flash SharedObject 使用的是kissystore模块来调用Flash SharedObjectFlash SharedObject的优点是容量适中,基本上不存在兼容性问题,缺点是要在页面中引入特定的swfjs文件,增加额外负担,处理繁琐;还是有部分机子没有flash运行环境。

    Google Gears Google的离线方案,已经停止更新,官方推荐使用html5localStorage方案。

    User Data 是微软为IE专门在系统中开辟的一块存储空间,所以说只支持Windows+IE的组合,实际测试在2000IE5.5)、XPIE6IE7),VistaIE7)下都是可以正常使用的。在XP下,一般位于C:\Documents and Settings\用户名\UserData,有些时候会在C:\Documents and Settings\用户名\Application Data\Microsoft\Internet Explorer\UserData。在Vista下,位于C:\Users\用户名\AppData\Roaming\Microsoft\Internet Explorer\UserData;单个文件的大小限制是128KB,一个域名下总共可以保存1024KB的文件,文件个数应该没有限制。在受限站点里这两个值分别是64KB640KB,所以如果考虑到各种情况的话,单个文件最好能控制64KB以下。

    localStorage 相对于上述本地存储方案,localStorage有自身的优点:容量大、易用、强大、原生支持;缺点是兼容性差些(chrome,  safari, firefoxIE 9IE8都支持 localStorage,主要是IE8以下版本不支持)、安全性也差些(所以请勿使用localStorage保存敏感信息)。

    主要说说localStorageUserData

    UserData

    • 基本语法 :
      XML: <Prefix: CustomTag id=sID style=
      behavior:url(#default#userData) />
      HTML: <ELEMENT style=
      behavior:url(#default#userData) id=sID>
    • Script:
      object.style.behavior =
      url(#default#userData)
      object.addBehavior (
      #default#userData)
    • 属性:
      expires
      设置或者获取 userData behavior 保存数据的失效日期。
      XMLDocument
      获取 XML 的引用。
    • 方法:
      getAttribute()
      获取指定的属性值。
      load(object)
      userData 存储区载入存储的对象数据。
      removeAttribute()
      移除对象的指定属性。
      save(object)
      将对象数据存储到一个 userData 存储区。
      setAttribute()
      设置指定的属性值。

    localStorage

    原生的接口:

    • localStorage.getItem(key):获取指定key本地存储的值
    • localStorage.setItem(key,value):将value存储到key字段
    • localStorage.removeItem(key):删除指定key本地存储的值
    • localStorage.clear() :清除所有键值
    • localStorage.length:键值长度
    • localStorage.key(i) :索引第i个键值 

    具体用法如下,已经封装好:

    View Code
      1 (function(){
    2 baiduUserData = {
    3 _data : null,
    4 _defExpires : null,
    5 _saveFile : null,
    6 setDefExpires : function(expires){
    7 var This = this;
    8 This._defExpires = expires || 365;
    9 },
    10 setSaveFile : function(s){
    11 var This = this;
    12 This._saveFile = s || window.location.hostname;
    13 },
    14 _init : function(){
    15 var This = this;
    16 if (!This._data){
    17 try {
    18 This._data = document.createElement('input');
    19 This._data.type = "hidden";
    20 This._data.addBehavior("#default#userData"); //这里一定是#default#userData
    21 document.body.appendChild(This._data);
    22 } catch(e){
    23 return false;
    24 }
    25 }
    26 return true;
    27 },
    28
    29 setItem : function(opt){ //opt={file: ,key: ,value: ,e: }
    30 var This = this;
    31 if(This._init()){
    32 This.setDefExpires(opt.e);
    33 var expires = new Date();
    34 expires.setDate(expires.getDate()+This._defExpires);
    35 This._data.expires = expires.toUTCString();
    36
    37 opt.value = typeof(opt.value) == "string" ? opt.value : T.json.stringify(opt.value);
    38 This.setSaveFile(opt.file);
    39 This._data.load(This._saveFile);
    40 This._data.setAttribute(opt.key,opt.value);
    41 This._data.save(This._saveFile);
    42 }
    43 },
    44
    45 getItem : function(opt){ //opt={file: ,key: }
    46 var This = this;
    47 if(This._init()){
    48 This.setSaveFile(opt.file);
    49 This._data.load(This._saveFile);
    50 return This._data.getAttribute(opt.key);
    51 }
    52 },
    53
    54 removeItem : function(opt){ //opt={file: ,key: }
    55 var This = this;
    56 if(This._init()){
    57 This.setSaveFile(opt.file);
    58 This._data.load(This._saveFile);
    59 This._data.removeAttribute(opt.key);
    60 This._data.save(This._saveFile);
    61 }
    62 }
    63 };
    64
    65
    66
    67 /*对外接口*/
    68
    69 baiduStorage = {
    70 /**
    71 * 调用baiduStorage.getItem({file: , key: });其中file可选,用于Userdata指定读取的文件名。key必选
    72 */
    73 getItem : function(opt){
    74 if(window.localStorage){
    75 return localStorage.getItem(opt.key);
    76 }
    77 else return baiduUserData.getItem(opt);
    78 },
    79 /**
    80 * 调用baiduStorage.setItem({file: , key: ,value:, e:}); key,value必选,file可选,用于Userdata指定读取的文件名.e可选,用于UserData指定到期时间
    81 */
    82 setItem : function(opt){
    83 if(window.localStorage){
    84 opt.value = typeof(opt.value) == "string" ? opt.value : T.json.stringify(opt.value);
    85 localStorage.setItem(opt.key,opt.value);
    86 }
    87 else baiduUserData.setItem(opt);
    88 },
    89 /**
    90 * 调用baiduStorage.removeItem({file: , key: ,clear:});其中file可选,用于Userdata指定读取的文件名.clear可选(boolean),true表示清空,false或空时就只remove掉key.
    91 */
    92 removeItem : function(opt){
    93 if(window.localStorage){
    94 if(opt.clear) localStorage.clear();
    95 else localStorage.removeItem(opt.key);
    96 }
    97 else baiduUserData.removeItem(opt);
    98 }
    99 };
    100 })();

     

     

    事件绑定:

    onStorage事件对象属性测试  以下是本人机子的测试结果

     

    key

    oldValue

    newValue

    url

    storageArea(json 格式,改变后所有的key:val)

    IE8

    Firefox6 

    Chrome15

    Safari5.1

    Opera10

    (多一个length,值为key的数量)

    此外,不同的浏览器事件注册的方式以及对象也不一致。

         onStorage事件注册对象,以下是本人机子的测试结果

     

    事件注册对象

    备注

    IE8

    document

     不能是window绑定

    Firefox6

    Window

     

    Chrome5

    Window

     

    Safari5.1

    Window

     

    Opera11.5

    window

     

     注:IE8既支持UserData又支持localStorage

        IE6,7不支持onstorage事件,需要用时间轮询来捕获键值的变化。

    以下是关于事件注册的代码

    View Code
     1 (function(){
    2 function myEvt(e){
    3 if(!e) e=window.event;
    4 alert("key---"+e.key);
    5 alert("newValue---"+e.newValue);
    6 alert("oldValue---"+e.oldValue);
    7 alert("url---"+e.url);
    8 alert("storageArea---"+T.json.stringify(e.storageArea));
    9 }
    10 if(window.addEventListener){
    11 window.addEventListener("storage",function(e){myEvt(e);},false);
    12 }
    13 else{
    14 document.attachEvent("onstorage",function(e){myEvt(e);});
    15 }
    16
    17 if(document.all){
    18 var old = baiduStorage.getItem({key:"a"});
    19 function checkUpdate(){
    20 var newV = baiduStorage.getItem({key:"a"});
    21 if(old != newV){
    22 alert(newV);
    23 old = newV;
    24 }
    25 }
    26 setInterval(function(){checkUpdate();},500);
    27 }
    28 })();

     

    以上的代码用到百度tangram定制的类库,用到T.json.stringify();

     

     

     

    Demo

    1,验证onstorage事件.打开两个tab。(除IE6,7外,都能alertonstorage事件的属性。IE6,7的只能alert出变化后的值).

    View Code
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    2 <html xmlns="http://www.w3.org/1999/xhtml">
    3 <head>
    4 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    5 <title>本地存储</title>
    6 <script type="text/javascript" src="tangram_stringify.js"></script>
    7 <script type="text/javascript" src="storage_api.js"></script>
    8 </head>
    9
    10 <body>
    11 <div id="ans1"></div>
    12 <script type="text/javascript">
    13 baiduStorage.setItem({key:"a",value:20});
    14 function changeData(){
    15 var t1 = baiduStorage.getItem({key:"a"});
    16 ++t1;
    17 alert(t1);
    18 baiduStorage.setItem({key:"a",value:t1});
    19 }
    20
    21 </script>
    22 <input type="button" id="ce" onclick="changeData();" value="改变键值"/>
    23 </body>
    24 </html>

    (点击此页面中的按钮,第二个页面会alert出事件的各个属性)。

    下面是第二个页面的代码

    View Code
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    2 <html xmlns="http://www.w3.org/1999/xhtml">
    3 <head>
    4 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    5 <title>本地存储</title>
    6 <script type="text/javascript" src="tangram_stringify.js"></script>
    7 <script type="text/javascript" src="storage_api.js"></script>
    8 <script type="text/javascript">
    9 (function(){
    10 function myEvt(e){
    11 if(!e) e=window.event;
    12 alert("key---"+e.key);
    13 alert("newValue---"+e.newValue);
    14 alert("oldValue---"+e.oldValue);
    15 alert("url---"+e.url);
    16 alert("storageArea---"+T.json.stringify(e.storageArea));
    17 }
    18 if(window.addEventListener){
    19 window.addEventListener("storage",function(e){myEvt(e);},false);
    20 }
    21 else{
    22 document.attachEvent("onstorage",function(e){myEvt(e);});
    23 }
    24
    25 if(document.all){
    26 var old = baiduStorage.getItem({key:"a"});
    27 function checkUpdate(){
    28 var newV = baiduStorage.getItem({key:"a"});
    29 if(old != newV){
    30 alert(newV);
    31 old = newV;
    32 }
    33 }
    34 setInterval(function(){checkUpdate();},500);
    35 }
    36 })();
    37 </script>
    38 </head>
    39
    40 <body>
    41 </body>
    42 </html>

     

    2.基于localStorageUserData模拟HI(同一浏览器下打开两个tab,在一个tab中输入信息后,第二个tab会跟进信息。兼容所有浏览器,包括IE6,7)

    View Code
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    2 <html xmlns="http://www.w3.org/1999/xhtml">
    3 <head>
    4 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    5 <title>基于localStorage和UserData模拟HI</title>
    6 <script type="text/javascript" src="storage_api.js"></script>
    7 <script type="text/javascript" src="tangram_stringify.js"></script>
    8 <style type="text/css">
    9 #wrap{margin:100px auto;height:500px;width:500px;border:1px solid #CCFFCC}
    10 #top{height:350px; overflow:scroll;}
    11 #sep{height:20px; background-color:#33CCFF}
    12 #content{height:125px;width:500px;}
    13 #s{float:right;}
    14 h1{color:#3300FF; font-size:24px; font-family:"宋体";margin:50px auto 0 auto; text-align:center;}
    15 #notice{display:none;}
    16 </style>
    17 </head>
    18
    19 <body>
    20 <h1>基于localStorage和UserData模拟HI</h1>
    21 <div id="wrap">
    22 <div id="top"></div>
    23 <div id="sep"></div>
    24 <textarea id="content" rows="5" onclick="HI.hide_notice();"></textarea>
    25 <input type="button" id="s" value="发送" onclick="HI.send();" />
    26 <p id="notice">发送内容不能为空</p>
    27 </div>
    28 <script type="text/javascript">
    29 var HI = {
    30 _content : null,
    31 init : function(){
    32 var This = this;
    33
    34 baiduStorage.setItem({key:"content",value:''});
    35 This._content = '';
    36
    37 if(window.addEventListener){
    38 window.addEventListener("storage",function(e){
    39 if(!e) e=window.event;
    40 This._content = baiduStorage.getItem({key:"content"});
    41 document.getElementById("top").innerHTML = This._content;
    42 },false);
    43 }
    44
    45 if(document.all){
    46 function checkUpdate(){
    47 var newV = baiduStorage.getItem({key:"content"});
    48 if(This._content != newV){
    49 document.getElementById("top").innerHTML = newV;
    50 This._content = newV;
    51 }
    52 }
    53 setInterval(function(){checkUpdate();},500);
    54 }
    55 },
    56 send : function(){
    57 var temp = document.getElementById("content").value.replace(/(^\s*)(\s*$)/g,'');
    58 if(temp == ''){
    59 document.getElementById("notice").style.display = "block";
    60 document.getElementById("content").value = "";
    61 return false;
    62 }
    63 var This = this;
    64 This._content = baiduStorage.getItem({key:"content"});
    65
    66 This._content += document.getElementById("content").value + '<br/>';
    67 baiduStorage.setItem({key:"content",value:This._content});
    68 document.getElementById("top").innerHTML = This._content;
    69 document.getElementById("content").value = '';
    70 },
    71 hide_notice: function(){
    72 document.getElementById("notice").style.display = "none";
    73 }
    74 }
    75 HI.init();
    76
    77 </script>
    78 </body>
    79 </html>

     下图是demo的效果:

     

     

    需要跟进的地方:

    1.    按照网上所说的UserData路径,在IE下的UserData文件仍然找不到。

    2.    自己封装的baiduStorageapi考虑到的需求可能不周,若有新需求可以跟进。

     

  • 相关阅读:
    GitHub 访问不顺怎么办?在线等,急
    深度解读最新版 Scrum 指南
    有奖体验 CODING 产品,iPad Pro、HHKB 键盘等超级礼包等你来!
    腾讯全资子公司 CODING 2021 届校园招聘正式开启!
    产品更新 | 「CODING 持续部署」新手体验:应用发布只需 30 秒!
    CODING 推出独立制品仓库 WePack,助力企业渐进式 DevOps 转型
    CODING DevOps 线下沙龙回顾一:DevOps 代码质量实战
    CODING 荣获「2020 DevOps 领域年度极具影响力产品」奖项
    CODING DevOps 产品认证学习计划正式启动!
    DevOps Workshop | 代码管理入门:基于代码扫描实现团队效率提升
  • 原文地址:https://www.cnblogs.com/winterIce/p/2179281.html
Copyright © 2020-2023  润新知