zoukankan      html  css  js  c++  java
  • 兼容多浏览器的本地存储

       在做考试系统时需要解决这样一个问题,就是当考生考试时可能出出现断网、关闭浏览器,刷新等问题,数据此时可能没有及时写入数据库,所以造成数据丢失问题,,所以这里就需要用到本地存储,以前的版本都是用cookie,但是不得不说cookie太小了,只有可怜的4k,而机房的网有时候实在是让人捉急,所以,考虑换一种方案。

    直接读取XML实现方式

        因为本地存储平时接触的不是太多,开始想的只是简单的读取本地的XML,做起来倒是挺容易的,一个语句就能搞定: 

    1. <script language="javascript"type="text/javascript">  
    2.                   var fso, f1, ts, s;  
    3.          varForReading = 1;  
    4.          fsonew ActiveXObject("Scripting.FileSystemObject");  
    5.          //创建文件  
    6.      f1 =fso.CreateTextFile("F:\testfile.txt", true);  
    7.          //填写一行数据  
    8.          f1.WriteLine("我是美丽的姑娘");  
    9.          f1.WriteBlankLines(1);  
    10.          //关闭文件  
    11.          f1.Close();  
    12.          //打开文件  
    13.          tsfso.OpenTextFile("F:\list.xml", ForReading);  
    14.           var nodes = ts.documentElement.childNodes;  
    15.          //读取文件一行内容到字符串  
    16.          sts.ReadLine();  
    17.          //显示字符串信息  
    18.          alert("文件信息是: "+s);  
    19.          //关闭文件  
    20.          ts.Close();  
    21.           
    22. </script>  



        但是这样写虽然简单,带来的弊端也不少,于是上网查到UserData可以解决这个问题。

    UserData实现方式:

        userData行为通过将数据写入一个UserData存储区(UserDatastore)来保存数据,userData可以将数据以XML格式保存在客户端计算机上,如果你用的是 Windows 2000 或者 Windows XP,是保存在C:Documents and SettingsLimingUserData文件夹下(如果操作系统不是安装在C盘,那么C就应该是操作系统所在的分区)。

        该数据将一直存在,除非你人为删除或者用脚本设置了该数据的失效期。

        userData行为提供了一个比Cookie更具有动态性和更大容量的数据结构。每页的UserData存储区数据大小可以达到64 Kb,每个域名可以达到640 Kb。

        userData行为通过sessions为每个对象分配UserData存储区。使用save和load方法将UserData存储区数据保存在缓存(cache)中。一旦UserData存储区保存以后,即使IE浏览器关闭或者刷新了,下一次进入该页面,数据也能够重新载入而不会丢失。

        但是,UserData是IE的东西,所以其他浏览器不兼容,当时,因为现在做的这个考试系统一般情况下都在UserData下使用,所以也实现了一下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <HTML>  
    2. <HEAD>  
    3. <STYLE>  
    4. .userData{behavior:url(#default#userdata);}  
    5. </STYLE>  
    6. <SCRIPT>  
    7. function fnSaveInput(){  
    8. var oPersist=oPersistForm.oPersistInput;  
    9. oPersist.setAttribute("sPersist",oPersist.value);//将oPersist.value存储为sPersist属性  
    10. oPersist.save("oXMLBranch"); //存储在名为oXMLBranch的UserData存储区  
    11. }  
    12. function fnLoadInput(){  
    13. var oPersist=oPersistForm.oPersistInput;  
    14.  varabc=oPersist.load("oXMLBranch"); //载入在名为oXMLBranch的UserData存储区  
    15. oPersist.value=oPersist.getAttribute("sPersist");//将sPersist属性赋值给oPersist.value  
    16. }  
    17. </SCRIPT>  
    18. </HEAD>  
    19. <BODY>  
    20. <FORM ID="oPersistForm">  
    21. <INPUT CLASS="userData"TYPE="text" ID="oPersistInput">  
    22. <INPUT TYPE="button"VALUE="Load" onclick="fnLoadInput()">  
    23. <INPUT TYPE="button"VALUE="Save" onclick="fnSaveInput()">  
    24. </FORM>  
    25. </BODY>  
    26. </HTML>  



    HTML5 LocalStorage   

        但是,毕竟UserData有他的局限性,处于兼容考虑,也在实现过程中听说了一种叫HTML5 LocalStorage 的东西。

    要介绍HTML5 LocalStorage,首先介绍一下本地存储的历史:


        从这里可以看出去,本地存储一路从Cookies走到最后,真心的不容易,那么,HTML5 LocalStorage 具体有什么好处呢?

        最早的Cookies自然是大家都知道,问题主要就是太小,大概也就4KB的样子,而且IE6只支持每个域名20个cookies,太少了。优势就是大家都支持,而且支持得还蛮好。很早以前那些禁用cookies的用户也都慢慢的不存在了,就好像以前禁用javascript的用户不存在了一样。

        userData是IE的东西。现在用的最多的是Flash,空间是Cookie的25倍,基本够用。再之后Google推出了Gears,虽然没有限制,但不爽的地方就是要装额外的插件。到了HTML5把这些都统一了,官方建议是每个网站5MB,非常大了,就存些字符串,足够了。比较诡异的是居然所有支持的浏览器目前都采用的5MB,尽管有一些浏览器可以让用户设置,但对于网页制作者来说,目前的形势就5MB来考虑是比较妥当的。

        那么,有哪些浏览器支持他呢?


        所以根据图我们可以看出,技术所以的浏览器都支持HTML5 LocalStorage,所以,这也让本地存储前途一片光明啊!

        下面写一个简单的实例: 

    1. <body>  
    2. <p>You have viewed this page <spanidspanid="count">0</span> time(s).</p>  
    3. <p><input type="button"value="changeStorage" onClick="changeS()"/></p>  
    4. <script>  
    5.          varstorage = window.localStorage;  
    6.           
    7.          if(!storage.getItem("pageLoadCount"))storage.setItem("pageLoadCount",0);  
    8.                    storage.pageLoadCountparseInt(storage.getItem("pageLoadCount")) + 1;//必须格式转换  
    9.                    document.getElementById("count").innerHTMLstorage.pageLoadCount;  
    10.                    showStorage();  
    11.                    if(window.addEventListener){  
    12.                     window.addEventListener("storage",handle_storage,false);  
    13.                    }elseif(window.attachEvent){  
    14.                     window.attachEvent("onstorage",handle_storage);  
    15.          }  
    16.           
    17.          functionhandle_storage(e){  
    18.                     if(!e){e=window.event;}  
    19.                     showObject(e);  
    20.          }  
    21.           
    22.          functionshowObject(obj){  
    23.                     //递归显示object  
    24.                     if(!obj){return;}  
    25.                              for(var i in obj){  
    26.                               if(typeof(obj[i])!="object" ||obj[i]==null){  
    27.                                  document.write(i+ " : " + obj[i] + "<br/>");  
    28.                               }   else{  
    29.                                  document.write(i+ " : object" + "<br/>");  
    30.                               }  
    31.                     }  
    32.          }  
    33.           
    34.          storage.setItem("a",5);  
    35.           
    36.          functionchangeS(){  
    37.                     //修改一个键值,测试storage事件  
    38.                     if(!storage.getItem("b")){storage.setItem("b",0);}  
    39.                            storage.setItem('b',parseInt(storage.getItem('b'))+1);  
    40.          }  
    41.           
    42.          functionshowStorage(){  
    43.                     //循环显示localStorage里的键值对  
    44.                     for(var i=0;i<storage.length;i++){  
    45.                               //key(i)获得相应的键,再用getItem()方法获得对应的值  
    46.                               document.write(storage.key(i)+ " :" + storage.getItem(storage.key(i)) + "<br>");  
    47.                     }  
    48.          }  
    49. </script>  
    50. </body>  



        当运行这个实例的时候,出现一个诡异的问题,就是其他浏览器还好,在IE下报错,所以,这也算是他的一个特点吧,它在IE、Firefox测试的时候需要把文件上传到服务器上(或者localhost),直接点开本地的HTML文件,是不行的,这里一定要注意。

        最后,这些demo都有了,我们详细的讲一下它的一些属性:


        到这里,基本上基本的概念和简单的demo就都清楚了,现在需要的就是把这些东西整合到一起,因为我们知道HTML5 LocalStorage不能支持IE8以下的浏览器,但是考试系统运行的环境大部分都在IE8以下,所以我们如果想做一个兼容性比较好的本地存储,就需要UserData和HTML5 LocalStorage连起来用,皇天不负有心人,在实现的过程中,我在网上找到了这样好的代码,毕竟以实现程序为主,又好使的,还是用用好使的吧。下面是代码:

    我是借鉴的代码哦

        但是这个文章里没有对命名空间给出代码,所以直接使用是有问题的,需要加入命名空间的代码,以下是我稍微改动了一下,并且适应于考试系统的代码:

    完整的demo

        HTML代码(注意,一定要放在服务器上运行,IIS,TOMCAL,JBOSS都可以,不要直接点击运行): 

    1. <!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    2. <htmlxmlnshtmlxmlns="http://www.w3.org/1999/xhtml">  
    3. <head>  
    4. <metahttp-equivmetahttp-equiv="Content-Type" content="text/html;charset=gb2312" />  
    5.    
    6. <title>无标题文档</title>  
    7.  <script type="text/javascript"src="js/jquery-1.4.2.min.js"></script>  
    8.    <script type="text/javascript" src="js/jquery.utils.js"></script>  
    9.  <script type="text/javascript"src="js/localstorage.js"></script>  
    10.    
    11.    
    12. <script>  
    13. function saveStu(){  
    14.          qext.LocalStorage.save("2344234","234","234234","234234");  
    15. }  
    16.    
    17.  function saveMore(){  
    18. // 保存多个对象  
    19. qext.LocalStorage.set([{  
    20.   key : "username",  
    21.   value : "{  ‘sitename’: ‘K JSON’, ‘siteurl’: ‘www.kjson.com’, ‘keyword’: ‘JSON在线校验,格式化JSON,json 在线校验’}",  
    22.    
    23.   expires : 3600 * 1000  /*单位:ms*/  
    24. },{  
    25.   key : "password",  
    26.   value : "zxlie",  
    27.   expires : 3600 * 1000  /*单位:ms*/  
    28. }]);  
    29. }   
    30. function show(){  
    31.          //获取某一个本地存储,返回值为:{key:"",value:"",expires:""},未取到值时返回值为:null  
    32.  varrst = qext.LocalStorage.get({  
    33.    key : "2344234234234234"  
    34.  });  
    35.  alert(rst);  
    36. }  
    37. function getMore(){  
    38.          vararrGet = qext.LocalStorage.getAllKeys();  
    39.          for(vari=0;i<arrGet.length;i++){  
    40.                    varrst = qext.LocalStorage.get({  
    41.                        key : arrGet[i]  
    42.                     });  
    43.                     alert(rst);  
    44.          }  
    45. }  
    46. function removeOne(){  
    47.          qext.LocalStorage.remove({  
    48.                     key : "2344234234234"  
    49.          })  
    50. }  
    51.    
    52. </script>  
    53. </head>  
    54.    
    55. <body>  
    56. <input type="button"onclick="saveStu()" value="保存数据" />  
    57. <input type="button"onclick="show()" value="显示数据" />  
    58. <input type="button"onclick="getMore()" value="显示全部数据" />  
    59. <input type="button"onclick="removeOne()" value="移除一个数据" />  
    60. </body>  
    61. </html>  



    JS代码: 

    1. /**  
    2.  * 注册命名空间  
    3.  *@param {String} fullNS 完整的命名空间字符串,如qui.dialog  
    4.  *@param {Boolean} isIgnorSelf 是否忽略自己,默认为false,不忽略  
    5.  *@author   
    6.  *@example  
    7.  *     window.registNS("QingFeed.Text.Bold");  
    8.  */  
    9. window.registNS =function(fullNS,isIgnorSelf){  
    10.    //命名空间合法性校验依据  
    11.    var reg = /^[_$a-z]+[_$a-z0-9]*/i;  
    12.           
    13.    // 将命名空间切成N部分, 比如baidu.libs.Firefox等  
    14.    var nsArray = fullNS.split('.');  
    15.    var sEval = "";  
    16.    var sNS = "";  
    17.    var n = isIgnorSelf ? nsArray.length - 1 : nsArray.length;  
    18.    for (var i = 0; i < n; i++){  
    19.        //命名空间合法性校验  
    20.         if(!reg.test(nsArray[i])) {  
    21.            throw new Error("Invalid namespace:" + nsArray[i] +"");  
    22.            return ;  
    23.        }  
    24.        if (i != 0) sNS += ".";  
    25.        sNS += nsArray[i];  
    26.        // 依次创建构造命名空间对象(假如不存在的话)的语句  
    27.        sEval += "if(typeof(" + sNS + ")=='undefined') " +sNS + "=new Object();else " + sNS + ";";  
    28.     }  
    29.    //生成命名空间  
    30.    if (sEval != "") {  
    31.        return eval(sEval);  
    32.     }  
    33.    return {};  
    34. };  
    35.    
    36.    
    37. /**  
    38.  * 注册命名空间  
    39.  */  
    40. window.registNS('qext');  
    41.    
    42. /**  
    43.  *@class qext.LocalStorage  
    44.  * 跨浏览器的本地存储实现。高级浏览器使用localstorage,ie使用UserData。虽然说是本地存储,也请不要存储过大数据,最好不要大于64K.  
    45.  * 因为ie下UserData每页最大存储是64k。  
    46.  *@singleton  
    47.  *@author zhaoxianlie (xianliezhao@foxmail.com)  
    48.  */  
    49. (function(){  
    50.    /**  
    51.     * 验证字符串是否合法的键名  
    52.     * @param {Object} key 待验证的key  
    53.     * @return {Boolean} true:合法,false:不合法  
    54.     * @private  
    55.     */  
    56.    function _isValidKey(key) {  
    57.        return (newRegExp("^[^\x00-\x20\x7f\(\)<>@,;:\\\"\[\]\?=\{\}\/\u0080-\uffff]+x24")).test(key);  
    58.     }  
    59.      
    60.    //所有的key  
    61.    var _clearAllKey = "_baidu.ALL.KEY_";  
    62.      
    63.    /**  
    64.     * 创建并获取这个input:hidden实例  
    65.     * @return {HTMLInputElement} input:hidden实例  
    66.     * @private  
    67.     */  
    68.    function _getInstance(){  
    69.        //把UserData绑定到input:hidden上  
    70.        var _input = null;  
    71.        //是的,不要惊讶,这里每次都会创建一个input:hidden并增加到DOM树种  
    72.        //目的是避免数据被重复写入,提早造成“磁盘空间写满”的Exception  
    73.        _input = document.createElement("input");  
    74.        _input.type = "hidden";  
    75.        _input.addBehavior("#default#userData");  
    76.        document.body.appendChild(_input);  
    77.        return _input;  
    78.     }  
    79.      
    80.    /**  
    81.     * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml  
    82.     * @param {String} key 待存储数据的key,和config参数中的key是一样的  
    83.     * @param {Object} config 待存储数据相关配置  
    84.     * @cofnig {String} key 待存储数据的key  
    85.     * @config {String} value 待存储数据的内容  
    86.     * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间  
    87.     * @private  
    88.     */  
    89.    function __setItem(key,config){  
    90.        try {  
    91.            var input = _getInstance();  
    92.            //创建一个Storage对象  
    93.            var storageInfo = config || {};  
    94.            //设置过期时间  
    95.            if(storageInfo.expires) {  
    96.                 var expires;  
    97.                 //如果设置项里的expires为数字,则表示数据的能存活的毫秒数  
    98.                 if ('number' == typeofstorageInfo.expires) {  
    99.                    expires = new Date();  
    100.                    expires.setTime(expires.getTime() + storageInfo.expires);  
    101.                 }  
    102.                 input.expires =expires.toUTCString();  
    103.            }  
    104.              
    105.            //存储数据  
    106.            input.setAttribute(storageInfo.key,storageInfo.value);  
    107.            //存储到本地文件,文件名为:storageInfo.key[1].xml  
    108.            input.save(storageInfo.key);  
    109.        } catch (e) {  
    110.        }  
    111.     }  
    112.    
    113.    /**  
    114.     * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml  
    115.     * @param {String} key 待存储数据的key,和config参数中的key是一样的  
    116.     * @param {Object} config 待存储数据相关配置  
    117.     * @cofnig {String} key 待存储数据的key  
    118.     * @config {String} value 待存储数据的内容  
    119.     * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间  
    120.     * @private  
    121.     */  
    122.    function _setItem(key,config){  
    123.        //保存有效内容  
    124.        __setItem(key,config);  
    125.          
    126.        //下面的代码用来记录当前保存的key,便于以后clearAll  
    127.        var result = _getItem({key : _clearAllKey});  
    128.        if(result) {  
    129.            result = {  
    130.                key : _clearAllKey,  
    131.                 value : result  
    132.            };  
    133.        } else {  
    134.            result = {  
    135.                 key : _clearAllKey,  
    136.                 value : ""  
    137.            };  
    138.        }  
    139.          
    140.        if(!(new RegExp("(^|\|)" + key + "(\||$)",'g')).test(result.value)){  
    141.            result.value += "|" + key;  
    142.            //保存键  
    143.            __setItem(_clearAllKey,result);      
    144.        }  
    145.     }  
    146.      
    147.    /**  
    148.     * 提取本地存储的数据  
    149.     * @param {String} config 待获取的存储数据相关配置  
    150.     * @cofnig {String} key 待获取的数据的key  
    151.     * @return {String} 本地存储的数据,获取不到时返回null  
    152.     * @example  
    153.     * qext.LocalStorage.get({  
    154.     *      key : "username"  
    155.     * });  
    156.     * @private  
    157.     */  
    158.    function _getItem(config){  
    159.        try {  
    160.            var input = _getInstance();  
    161.            //载入本地文件,文件名为:config.key[1].xml  
    162.            input.load(config.key);  
    163.            //取得数据  
    164.            return input.getAttribute(config.key) || null;  
    165.        } catch (e) {  
    166.            return null;             
    167.        }  
    168.     }  
    169.      
    170.    /**  
    171.     * 移除某项存储数据  
    172.     * @param {Object} config 配置参数  
    173.     * @cofnig {String} key 待存储数据的key  
    174.     * @private  
    175.     */  
    176.    function _removeItem(config){  
    177.                    try{  
    178.                             varinput = _getInstance();  
    179.                             //载入存储区块  
    180.                             input.load(config.key);  
    181.                             //移除配置项  
    182.                             input.removeAttribute(config.key);  
    183.                             //强制使其过期  
    184.                             varexpires = new Date();  
    185.                             expires.setTime(expires.getTime()- 1);  
    186.                             input.expiresexpires.toUTCString();  
    187.                             input.save(config.key);  
    188.                              
    189.                             //从allkey中删除当前key                        
    190.                             //下面的代码用来记录当前保存的key,便于以后clearAll  
    191.                             var result = _getItem({key :_clearAllKey});  
    192.                             if(result){  
    193.                                      resultresult.replace(new RegExp("(^|\|)" + config.key +"(\||$)",'g'),'');  
    194.                                      result= {  
    195.                                                key: _clearAllKey,  
    196.                                                value: result  
    197.                                      };  
    198.                                      //保存键  
    199.                                      __setItem(_clearAllKey,result);        
    200.                             }  
    201.                              
    202.                    }catch (e) {  
    203.                    }  
    204.          }  
    205.      
    206.    //移除所有的本地数据  
    207.    function _clearAll(){  
    208.        result = _getItem({key : _clearAllKey});  
    209.        if(result) {  
    210.            var allKeys = result.split("|");  
    211.            var count = allKeys.length;  
    212.            for(var i = 0;i < count;i++){  
    213.                 if(!!allKeys[i]) {  
    214.                    _removeItem({key:allKeys[i]});  
    215.                 }  
    216.            }  
    217.        }  
    218.     }  
    219.      
    220.      
    221.    /**  
    222.     * 获取所有的本地存储数据对应的key  
    223.     * @return {Array} 所有的key  
    224.     * @private  
    225.     */  
    226.    function _getAllKeys(){  
    227.        var result = [];  
    228.        var keys = _getItem({key : _clearAllKey});  
    229.        if(keys) {  
    230.            keys = keys.split('|');  
    231.            for(var i = 0,len = keys.length;i < len;i++){  
    232.                 if(!!keys[i]) {  
    233.                     result.push(keys[i]);  
    234.                 }  
    235.            }  
    236.        }  
    237.        return result ;  
    238.     }  
    239.      
    240.    /**  
    241.     * 判断当前浏览器是否支持本地存储:window.localStorage  
    242.     * @return {Boolean} true:支持;false:不支持  
    243.     * @remark 支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    244.     * @private  
    245.     */  
    246.    var _isSupportLocalStorage = (('localStorage' in window) &&(window['localStorage'] !== null)),  
    247.        _isSupportUserData = !!jQuery.browser.ie;  
    248.      
    249.    qext.LocalStorage = {  
    250.        /**  
    251.         * 如果支持本地存储,返回true;否则返回false  
    252.         * @type Boolean  
    253.         */  
    254.        isAvailable : _isSupportLocalStorage || _isSupportUserData,  
    255.          
    256.        /**  
    257.         * 将数据进行本地存储(只能存储字符串信息)  
    258.         * <pre><code>  
    259.                     * //保存单个对象  
    260.                     * qext.LocalStorage.set({  
    261.                     *             key: "username",  
    262.                     *             value: "baiduie",  
    263.                     *             expires: 3600 * 1000  
    264.                     * });  
    265.                     * //保存对个对象  
    266.                     * qext.LocalStorage.set([{  
    267.                     *             key: "username",  
    268.                     *             value: "baiduie",  
    269.                     *             expires: 3600 * 1000  
    270.                     * },{  
    271.                     *             key: "password",  
    272.                     *             value: "zxlie",  
    273.                     *             expires: 3600 * 1000  
    274.                     * }]);  
    275.         * </code></pre>  
    276.         * @param {Object} obj 待存储数据相关配置,可以是单个JSON对象,也可以是由多个JSON对象组成的数组  
    277.         * <ul>  
    278.         * <li><b>key</b> : String <divclassdivclass="sub-desc">待存储数据的key,务必将key值起的复杂一些,如:baidu.username</div></li>  
    279.         * <li><b>value</b> : String <divclassdivclass="sub-desc">待存储数据的内容</div></li>  
    280.         * <li><b>expires</b> : String/Object (Optional)<divclassdivclass="sub-desc">数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间</div></li>  
    281.         * </ul>  
    282.         */  
    283.        set : function(obj){  
    284.                             //保存单个对象  
    285.                             var_set_ = function(config){  
    286.                                      //key校验  
    287.                                      if(!_isValidKey(config.key)){return;}  
    288.    
    289.                                      //待存储的数据  
    290.                                      varstorageInfo = config || {};  
    291.                                       
    292.                                      //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    293.                                      if(_isSupportLocalStorage){  
    294.                                                window.localStorage.setItem(storageInfo.key,storageInfo.value);  
    295.                                                if(config.expires){  
    296.                         var expires;  
    297.                         //如果设置项里的expires为数字,则表示数据的能存活的毫秒数  
    298.                         if ('number' == typeofstorageInfo.expires) {  
    299.                             expires = newDate();  
    300.                            expires.setTime(expires.getTime() + storageInfo.expires);  
    301.                         }  
    302.    
    303.                        window.localStorage.setItem(storageInfo.key +".expires",expires);  
    304.                                                }  
    305.                                      }else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式  
    306.                                                _setItem(config.key,storageInfo);  
    307.                                      }         
    308.                             };  
    309.    
    310.                             //判断传入的参数是否为数组  
    311.                             if(obj&& obj.constructor === Array && obj instanceof Array){  
    312.                                      for(vari = 0,len = obj.length;i < len;i++){  
    313.                                                _set_(obj[i]);  
    314.                                      }  
    315.                             }elseif(obj){  
    316.                                      _set_(obj);  
    317.                             }  
    318.        },  
    319.                     
    320.                    /**  
    321.                     * 提取本地存储的数据  
    322.         * <pre><code>  
    323.                     * //获取某一个本地存储,返回值为:{key:"",value:"",expires:""},未取到值时返回值为:null  
    324.                     * var rst = qext.LocalStorage.get({  
    325.                     *             key: "username"  
    326.                     * });  
    327.                     * //获取多个本地存储,返回值为:["","",""],未取到值时返回值为:[null,null,null]  
    328.                     * qext.LocalStorage.get([{  
    329.                     *             key: "username"  
    330.                     * },{  
    331.                     *             key: "password"  
    332.                     * },{  
    333.                     *             key: "sex"  
    334.                     * }]);  
    335.         * </code></pre>  
    336.                     * @param {String} obj 待获取的存储数据相关配置,支持单个对象传入,同样也支持多个对象封装的数组格式  
    337.                     * @config {String} key 待存储数据的key  
    338.                     * @return {String} 本地存储的数据,传入为单个对象时,返回单个对象,获取不到时返回null;传入为数组时,返回为数组  
    339.                     */  
    340.        get : function(obj){  
    341.                             //获取某一个本地存储  
    342.                             var_get_ = function(config){  
    343.                                      //结果       
    344.                                      varresult = null;  
    345.                                      if(typeofconfig === "string") config = {key : config};  
    346.                                      //key校验  
    347.                                      if(!_isValidKey(config.key)){return result;}  
    348.                                       
    349.                                      //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    350.                                      if(_isSupportLocalStorage){  
    351.                                                resultwindow.localStorage.getItem(config.key);  
    352.                                                //过期时间判断,如果过期了,则移除该项  
    353.                                                if(result){  
    354.                                                         varexpires = window.localStorage.getItem(config.key + ".expires");  
    355.                                                         result= {  
    356.                                                                  value: result,  
    357.                                                                  expires: expires ? new Date(expires) : null  
    358.                                                         };  
    359.                                                         if(result&& result.expires && result.expires < new Date()) {  
    360.                                                                  resultnull;  
    361.                                                                  window.localStorage.removeItem(config.key);  
    362.                            window.localStorage.removeItem(config.key + ".expires");  
    363.                                                         }  
    364.                                                }  
    365.                                      }else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式  
    366.                                                //这里不用单独判断其expires,因为UserData本身具有这个判断  
    367.                                                result_getItem(config);  
    368.                                                if(result){  
    369.                                                         result= { value : result };  
    370.                                                }  
    371.                                      }  
    372.                                       
    373.                                      returnresult ? result.value : null;  
    374.                             };  
    375.                              
    376.                             varrst = null;  
    377.                             //判断传入的参数是否为数组  
    378.                             if(obj&& obj.constructor === Array && obj instanceof Array){  
    379.                                      rst= [];  
    380.                                      for(vari = 0,len = obj.length;i < len;i++){  
    381.                                                rst.push(_get_(obj[i]));  
    382.                                      }  
    383.                             }elseif(obj){  
    384.                                      rst_get_(obj);  
    385.                             }  
    386.                             returnrst;  
    387.        },  
    388.          
    389.        /**  
    390.         * 移除某一项本地存储的数据  
    391.         * <pre><code>  
    392.                     * //删除一个本地存储项  
    393.                     * qext.LocalStorage.remove({  
    394.                     *             key: "username"  
    395.                     * });  
    396.                     * //删除多个本地存储项目 *  
    397.                     * qext.LocalStorage.remove([{  
    398.                     *             key: "username"  
    399.                     * },{  
    400.                     *             key: "password"  
    401.                     * },{  
    402.                     *             key: "sex"  
    403.                     * }]);  
    404.         * </code></pre>  
    405.                     * @param {String} obj 待移除的存储数据相关配置,支持移除某一个本地存储,也支持数组形式的批量移除  
    406.                     * @config {String} key 待移除数据的key  
    407.                     * @return 无  
    408.         */  
    409.        remove : function(obj){  
    410.                             //移除某一项本地存储的数据  
    411.                             var_remove_ = function(config){  
    412.                                      //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    413.                                      if(_isSupportLocalStorage){  
    414.                                                window.localStorage.removeItem(config.key);  
    415.                                                window.localStorage.removeItem(config.key+ ".expires");  
    416.                                      }else if(_isSupportUserData){ //IE7及以下版本,采用UserData方式  
    417.                                                _removeItem(config);  
    418.                                      }  
    419.                             };  
    420.                              
    421.                             //判断传入的参数是否为数组  
    422.                             if(obj&& obj.constructor === Array && obj instanceof Array){  
    423.                                      for(vari = 0,len = obj.length;i < len;i++){  
    424.                                                _remove_(obj[i]);  
    425.                                      }  
    426.                             }elseif(obj){  
    427.                                      _remove_(obj);  
    428.                             }  
    429.        },  
    430.          
    431.        /**  
    432.         * 清除所有本地存储的数据  
    433.         * <pre><code>  
    434.         * qext.LocalStorage.clearAll();  
    435.         * </code></pre>  
    436.         */  
    437.        clearAll : function(){  
    438.            //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    439.            if(_isSupportLocalStorage) {  
    440.                 window.localStorage.clear();  
    441.            } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式  
    442.                 _clearAll();  
    443.            }  
    444.        },  
    445.          
    446.        //保存单个对象到本地  
    447.        save:function(StudentID,ExamID,QuestionID,ExamAnswer){  
    448.        qext.LocalStorage.set({  
    449.           key : StudentID+ExamID+QuestionID,  
    450.           value : "{  StudentID’: ‘"+StudentID+"’,‘ExamID’: ‘"+ExamID+"’, ‘QuestionID’:‘"+QuestionID+"’,‘ExamAnswer’: ‘"+ExamAnswer+"’}",  
    451.           expires : 3600 * 1000  /*单位:ms*/  
    452.        });  
    453.        },  
    454.        /**  
    455.         * 获取所有的本地存储数据对应的key  
    456.         * <pre><code>  
    457.         * var keys = qext.LocalStorage.getAllKeys();  
    458.         * </code></pre>  
    459.         * @return {Array} 所有的key  
    460.         */  
    461.        getAllKeys : function(){  
    462.            var result = [];  
    463.            //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+  
    464.            if(_isSupportLocalStorage) {  
    465.                 var key;  
    466.                 for(var i = 0,len =window.localStorage.length;i < len;i++){  
    467.                     key = window.localStorage.key(i);  
    468.                    if(!/.+.expires$/.test(key)) {  
    469.                         result.push(key);  
    470.                     }  
    471.                 }  
    472.            } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式  
    473.                 result = _getAllKeys();  
    474.            }  
    475.              
    476.            return result;  
    477.        }  
    478.    };  
    479.    
    480. })();  



    挺佩服封装这个代码的人,感觉无论从编程习惯还是代码的质量上都值得每一个人学习,所以,推荐一下。

    到此,所有的本地存储的问题都解决了,又是完美的一天!

    下面是一个完整的程序:我是完整的程序

    参考博客:http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html

    http://www.baidufe.com/item/af0bb5872f2a1ef337ce.html

  • 相关阅读:
    history对象
    排序算法总结
    Boltzmann机
    Sort Colors
    First Missing Positive
    Sort List
    Insertion Sort List
    Merge Two Sorted Lists
    Merge Sorted Array
    Sum Root to Leaf Numbers
  • 原文地址:https://www.cnblogs.com/web100/p/js-userdata.html
Copyright © 2011-2022 走看看