html5 - Storage 本地存储

Storage的解释 http://www.w3school.com.cn/html5/html_5_webstorage.asp

简单的理解就是:

Storage 有两种:

1、localStorage 永久性存储客户端、除非你删除、修改否则不会消失,存储的体积为5M (《HTML5程序设计》讲其实是可以超过5M只不过有的浏览器会提示有的则不提示.ps:我没测过书上说的)同时数据共享,也就说 其他页面也可以你访问到你存储的数据;

2、sessionStorage 临时性存储在客户端,只要你不关闭当前页面存数数据都在,数据不共享,其真正的用意是为了解决 cookie封堵数据泄露(简单说就是你在这个页面选择A选项 存到了cookie、你又开了同个页面选择B选项存到了cookie、回到A页面提交了选项 但cookie的值其实是B选项不是当前页面的A选项)

根据 jquery.cookie.js 编写了一个 Storage 的jquery 的简单粗鄙库,API 也是根据 cookie 编写:

$.isSession、$.isLocal 判断当前浏览器是否支持 Storage 两个属性的方法 支持为 true 不支持为undefined;

$.storage 存数本地数据的函数:三个参数 name、key、value 三个值 第一个参数为session、local 来分辨存储的是哪一种存储类型 第二参数为 存储的key 值 第三个参数为key对应的value值 如果 value 传的参数为‘’ 则视为删除这组key值,如果只传第一个参数为session、local则返回对应的原生对象 ,如果传了两个参数视为从本地存储里取key值的value,如果没有则返回undefined. 因为低版本的IE不支持Storage 会alert('This browser does NOT support Storage!'),建议如果做低版本的时候先用 $.isSession、$.isLoca 来判断一下客户端是否支持;

$.removeStorage 删除本地存数的key值:两个参数 第一个参数name 传参数session、local 一样分别删除哪种类型的本地存储,第二个参数key 为删除的key名,如果key传入的是‘clearAll’则视为清除全部对应本地存储的key值

$.wachStorage 为时时监控本地存储key的变化函数:一个参数为回调函数

(function (factory) {

    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // CommonJS
        factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }

}(function ($) {

    function _isStorageText( name ){ 
        if( name ==='session' || name === 'local' ){
            return true;
        }else{
            return false;
        }
    }

    var storageBrowser = {};

    if( window.sessionStorage ){

        storageBrowser.isStorage = true;
        
    }

    if( window.localStorage ){
        
        storageBrowser.isLocal = true;
    
    }
    
    $.isSession = storageBrowser.isStorage;
    $.isLocal = storageBrowser.isLocal;
    
    $.storage = function( name,key,value ){

        if( !$.isSession || !$.isLocal ){
            alert( 'This browser does NOT support Storage!' );
            return false;
        }

        if( arguments.length === 1 && !$.isFunction(name) && _isStorageText(name) ){
            switch( name )
            {
                case 'session':
                       return window.sessionStorage ;
                  break;
                case 'local':
                       return window.localStorage ;
                  break;
                default:
                      
            }
            
        }

        if(  arguments.length === 2 && !$.isFunction(name) && !$.isFunction(key)  && _isStorageText(name) ){
            switch( name )
            {
                case 'session':
                       return sessionStorage[ key ] ;
                  break;
                case 'local':
                       return localStorage[ key ] ;
                  break;
                default:
                      
            }
        }
        
        if(  arguments.length === 3 && !$.isFunction(name) && !$.isFunction(key) && !$.isFunction(value) && _isStorageText(name)   ){
            switch( name )
            {
                case 'session':
                    if ( $.trim(value).length === 0 && !$.isFunction(value)) {

                        return sessionStorage.removeItem(key);

                    }else{
                        
                        try {

                            return sessionStorage[ key ] = value;
                        
                        }catch(e) {}
                    }
                  break;
                case 'local':
                    if ( $.trim(value).length === 0 && !$.isFunction(value)) {

                        return localStorage.removeItem(key);

                    }else{

                        try {

                            return localStorage[ key ] = value;
                        
                        }catch(e) {}
                        
                    }
                       
                  break;
                default:
                      
            }
        }

        return false;

    } 


    //删除localStorage 的key值;
    $.removeStorage = function( name,key ){

        if( arguments.length === 1 && !$.isFunction(name) && _isStorageText(name) ){

            return false;

        }

        switch( name )
        {
            case 'session':
                 if( key === 'clearAll' ){
                     sessionStorage.clear();
                     return false;
                 }else{
                     return sessionStorage[ key ] ;
                 }
                   
              break;
            case 'local':
                   if( key === 'clearAll' ){
                     localStorage.clear();
                     return false;
                 }else{
                     return localStorage[ key ] ;
                 }
              break;
            default:
                  
        }

    }

    //时时监听 Storage 的变化;
    $.wachStorage = function( fn ){

        if( window.addEventListener ){

            window.addEventListener('storage',fn,true);

        }else{

            window.attachEvent('storage',fn);

        }

    }

}));

写了一个小小DEMO 数据同步:同时在服务端打开两个以上的页面查看在单页面选的喜欢的水果同步到另外几个相同页面(我没有做兼容,其实就是试试我写的小插件)。

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{margin:0;padding:0;}
    .cent{ width:950px; margin:0 auto;}
    li{ list-style:none;}
    </style>
    <script src="jquery-1.7.2.min.js"></script>
    <script src="jquery.storage.js"></script>
<script>
$(function(){

        var $checkboxs = $('input:checkbox');
        var $spans = $('span');
        var $btn = $('#btn');
        var $viwMian = $('#viwMian');

        // 初始化 判断是否有存储过本地数据
        StorageInit();
        function StorageInit(){
            fnStorage( function(){

                if( $.storage('local','fruit') ){
                    
                    var fruitArr = $.storage('local','fruit').split("&");
                    for( var j=0,len=fruitArr.length;j<len;j++ ){ 

                        for( var i=0,len=$spans.length;i<len;i++ ){
                            
                            var spanVlue = $spans.eq(i).text();
                            
                            if( spanVlue == fruitArr[j] ){

                                $spans.eq(i).prev().attr('checked','checked');
                                
                            }
                        }
                    }

                }


            } );
        }

        // 判断浏览器是否支持
        function fnStorage( fn ){
            if( $.isLocal ){

                fn();

            }    
        }

        //监控函数
        function SyncFruit( e ){

            if( e.key == 'fruit' ){
                
                for( var i=0,len=$spans.length;i<len;i++ ){
                    $spans.eq(i).prev().attr('checked',false);
                }
                var newKey = e.newValue;
                if( e.newValue ){
                    
                    var fruitArr = e.newValue.split("&");
                    for( var j=0,len=fruitArr.length;j<len;j++ ){ 

                        for( var i=0,len=$spans.length;i<len;i++ ){
                            
                            var spanVlue = $spans.eq(i).text();
                            
                            if( spanVlue == fruitArr[j] ){

                                $spans.eq(i).prev().attr('checked','checked');
                                
                            }
                        }
                    }
                }
                
            
            }
        }

        //调用的删除
        //$.removeStorage('local','clearAll');

        //监控的调用
        $.wachStorage( SyncFruit );
        
        //多选checkbox的点击事件
        $checkboxs.on('click',function(){

            var $this = $(this);
            var value = $(this).next().text();

            if( $this.attr('checked') == 'checked' ){
                    
                fnStorage(function(){

                    if( $.storage('local','fruit') ){
                        
                        var fruitTxt = $.storage('local','fruit');
                        fruitTxt += '&'+value;
                        $.storage('local','fruit',fruitTxt);

                    }else{

                        $.storage('local','fruit',value);

                    }

                });

            }else{
                
                fnStorage(function(){

                    var fruitArr = $.storage('local','fruit').split("&");
                    for( var i=0,len=fruitArr.length;i<len;i++ ){

                        if( fruitArr[ i ] == value ){
                            fruitArr.splice(i,1);
                        }

                    }
                    var fruitTxt = fruitArr.join("&");

                    $.storage('local','fruit',fruitTxt);

                });

                

            }
        });

        // 确定的提交
        $btn.on('click',function(){
            

            fnStorage(function(){

                var html = '',
                arr = []; 
                $viwMian.html('');
                if( $.storage('local','fruit') ){
                    
                    var fruitArr = $.storage('local','fruit').split("&");
                    
                    html += '我选择的有:<br/>'
                    for( var j=0,len=fruitArr.length;j<len;j++ ){ 

                        html+='<p>'+ fruitArr[j] +'</p>';
                        
                    }


                     $viwMian.append(html);

                }

            });
            
        });
        
    
});
</script>
    
</head>
<body>
    <div class="cent">
        <h2>
            选出喜欢的水果(多选题):
        </h2>
        <ul>
            <li>
                <input type="checkbox"><span>草莓</span>
            </li>
            <li>
                <input type="checkbox"><span>苹果</span>
            </li>
            <li>
                <input type="checkbox"><span>香蕉</span>
            </li>
            <li>
                <input type="checkbox"><span>鸭梨</span>
            </li>
            <li>
                <input type="checkbox"><span>桃子</span>
            </li>
            <li>
                <input type="checkbox"><span>火龙果</span>
            </li>
        </ul>
        <input type="button" value="确认" ><br/><br/>
        <div >
        
        </div>
    </div>
    
</body>
</html>

后记:

原本想在做了Storage 的 length 属性 查看存数的个数,后来觉得没啥太大用。。。。

这个小插件写的有点代码繁琐,我感觉还可以在简练一些,不过没想到更好的方式,如果有大神有好方法请告知;