HTML5 LocalStorage 本地存儲的用法

本地存儲變量b的值:javascript

localStorage.setItem("b","isaac");html

本地獲取變量b的值:java

localStorage.getItem("b");node

本地清除b的值:json

localStorage.removeItem("b");瀏覽器

另外,目前javascript使用很是多的json格式,若是但願存儲在本地,能夠直接調用JSON.stringify()將其轉爲字符串。讀取出來後調用JSON.parse()將字符串轉爲json格式,以下所示:安全

var details = {author:"isaac","description":"fresheggs","rating":100};
storage.setItem("details",JSON.stringify(details));
details = JSON.parse(storage.getItem("details"));cookie

 

即便是存儲cookie,能夠直接調用JSON.stringify()將其轉爲字符串。讀取出來後調用JSON.parse()將字符串轉爲json格式,(若是不轉換會報錯以致於沒法獲取值)以下所示:app

var details = {author:"isaac","description":"fresheggs","rating":100};
$.cookie("details",JSON.stringify(details));
details = JSON.parse($.cooki("details"));函數

 

本地化存儲(localStorage) 組件:

/*!
 * 本地化存儲(localStorage) 組件
 *
 * 版權全部(C) 2013 馬超 (zjcn5205@yeah.net)
 *
 * 這一程序是自由軟件,你能夠遵守自由軟件基金會出版的GNU通用公共許可證條款來修改和從新發布
 * 這一程序。或者用許可證的第二版,或者(根據你的選擇)用任何更新的版本。
 * 發佈這一程序的目的是但願它有用,但沒有任何擔保。甚至沒有適合特定目的的隱含的擔保。更詳細
 * 的狀況請參閱GNU通用公共許可證。
 * 你應該已經和程序一塊兒收到一份GNU通用公共許可證的副本。若是尚未,寫信給:
 * The Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA02139, USA
 */
/*
 *[功能描述]
 * 給不支持本地存儲的瀏覽器建立一個 window.localStorage 對象來提供相似接口
 * 該對象支持如下方法或屬性
    setItem : function(key, value)
    getItem : function(key)
    removeItem : function(key)
    clear : function()
    length : int
    key : function(i)
    isVirtualObject : true
 * 二次包裝的接口 window.LS 提供如下方法和屬性(若是有jQuery則一樣會擴展該對象),推薦使用
    set : function(key, vlaue)
    get : function(key)
    remove : function(key)
    clear : function()
    each : function(callback) callback接受兩個參數 key 和 value
    obj : function() 返回一個對象描述的localStorage副本
    length : int
 *
 *[已知問題、使用限制]
 * 原生本地存儲的key是區分大小寫的,模擬對象不區分(由於userData不區分key的大小寫)
 * 模擬對象的 clear 方法僅僅能清理經過本組件設定的數據
 * 模擬對象的實際的存儲容量跟原生本地存儲有差別
 * 模擬對象不支持任何localStorage事件件
 *
 *[更新日誌]
 * 2012-06-20 馬超 建立
 * 2012-06-27 馬超 增長clear相關方法和屬性
 * 2012-07-02 馬超 修改節點存儲方式
 * 2012-07-03 馬超 增長二次包裝以優化接口使用
 * 2012-07-04 馬超 修改內部邏輯,取消原有的單獨存儲key的方案,修改查詢不存在key的時候的默認值爲undefined
 * 2012-07-05 馬超 增長二次包裝的obj方法
 * 2013-03-06 胡志明 基於瑞星的劉瑞明提供的方案,兼容360急速瀏覽器IE模式(IE6),下降瀏覽器自帶localStorage優先級,優先使用userData。
 * 2013-03-11 胡志明 恢復iframe代理建立head標籤用戶存儲數據,修正了userData沒法垮目錄讀寫問題
 * 2013-03-14 胡志明 對部分沒法建立iframe代理的瀏覽器嘗試使用自帶localStorage,若是不自帶則暫時不支持本地存儲
 * 2013-03-18 馬超 優化加載判斷邏輯和代碼,以最大限度保證組件可用
 * 2013-04-23 馬超 增長更多的錯誤處理,進一步提升瀏覽器的兼容性
 * 2013-05-04 馬超 增長對userData的key的無效字符的轉義處理功能
 * 2013-06-06 馬超 優先探測本地存儲,解決IE9下userData使用問題(刷新頁面後無效)
 */
(function(window){
    //準備模擬對象、空函數等
    var LS, noop = function(){}, document = window.document, notSupport = {set:noop,get:noop,remove:noop,clear:noop,each:noop,obj:noop,length:0};
    
    //優先探測userData是否支持,若是支持,則直接使用userData,而不使用localStorage
    //以防止IE瀏覽器關閉localStorage功能或提升安全級別(*_* 萬惡的IE)
    //萬惡的IE9(9.0.11)),使用userData也會出現相似seesion同樣的效果,刷新頁面後設置的東西就沒有了...
    //只好優先探測本地存儲,不能用再嘗試使用userData
    (function(){
        // 先探測本地存儲 2013-06-06 馬超
        // 嘗試訪問本地存儲,若是訪問被拒絕,則繼續嘗試用userData,注: "localStorage" in window 卻不會返回權限錯誤
        // 防止IE10早期版本安全設置有問題致使的腳本訪問權限錯誤
        if( "localStorage" in window ){
            try{
                LS = window.localStorage;
                return;
            }catch(e){
                //若是報錯,說明瀏覽器已經關閉了本地存儲或者提升了安全級別
                //則嘗試使用userData
            }
        }
        
        //繼續探測userData
        var o = document.getElementsByTagName("head")[0], hostKey = window.location.hostname || "localStorage", d = new Date(), doc, agent;
        
        //typeof o.addBehavior 在IE6下是object,在IE10下是function,所以這裏直接用!判斷
        //若是不支持userData則跳出使用原生localStorage,若是原生localStorage報錯,則放棄本地存儲
        if(!o.addBehavior){
            try{
                LS = window.localStorage;
            }catch(e){
                LS = null;
            }
            return;
        }
        
        try{ //嘗試建立iframe代理,以解決跨目錄存儲的問題
            agent = new ActiveXObject('htmlfile');
            agent.open();
            agent.write('<s' + 'cript>document.w=window;</s' + 'cript><iframe src="/favicon.ico"></iframe>');
            agent.close();
            doc = agent.w.frames[0].document;
            //這裏經過代理document建立head,可使存儲數據垮文件夾訪問
            o = doc.createElement('head');
            doc.appendChild(o);
        }catch(e){
            //不處理跨路徑問題,直接使用當前頁面元素處理
            //不能跨路徑存儲,也能知足多數的本地存儲需求
            //2013-03-15 馬超
            o = document.getElementsByTagName("head")[0];
        }
        
        //初始化userData
        try{
            d.setDate(d.getDate() + 36500);
            o.addBehavior("#default#userData");
            o.expires = d.toUTCString();
            o.load(hostKey);
            o.save(hostKey);
        }catch(e){
            //防止部分外殼瀏覽器的bug出現致使後續js沒法運行
            //若是有錯,放棄本地存儲
            //2013-04-23 馬超 增長
            return;
        }
        //開始處理userData
        //如下代碼感謝瑞星的劉瑞明友情支持,作了大量的兼容測試和修改
        //並處理了userData設置的key不能以數字開頭的問題
        var root, attrs;
        try{
            root = o.XMLDocument.documentElement;
            attrs = root.attributes;
        }catch(e){
            //防止部分外殼瀏覽器的bug出現致使後續js沒法運行
            //若是有錯,放棄本地存儲
            //2013-04-23 馬超 增長
            return;
        }
        var prefix = "p__hack_", spfix = "m-_-c",
            reg1 = new RegExp("^"+prefix),
            reg2 = new RegExp(spfix,"g"),
            encode = function(key){ return encodeURIComponent(prefix + key).replace(/%/g, spfix); },
            decode = function(key){ return decodeURIComponent(key.replace(reg2, "%")).replace(reg1,""); };
        //建立模擬對象
        LS= {
            length: attrs.length,
            isVirtualObject: true,
            getItem: function(key){
                //IE9中 經過o.getAttribute(name);取不到值,因此才用了下面比較複雜的方法。
                return (attrs.getNamedItem( encode(key) ) || {nodeValue: null}).nodeValue||root.getAttribute(encode(key));
            },
            setItem: function(key, value){
                //IE9中沒法經過 o.setAttribute(name, value); 設置#userData值,而用下面的方法卻能夠。
                try{
                    root.setAttribute( encode(key), value);
                    o.save(hostKey);
                    this.length = attrs.length;
                }catch(e){//這裏IE9常常報沒權限錯誤,可是不影響數據存儲
                }
            },
            removeItem: function(key){
                //IE9中沒法經過 o.removeAttribute(name); 刪除#userData值,而用下面的方法卻能夠。
                try{
                    root.removeAttribute( encode(key) );
                    o.save(hostKey);
                    this.length = attrs.length;
                }catch(e){//這裏IE9常常報沒權限錯誤,可是不影響數據存儲
                }
            },
            clear: function(){
                while(attrs.length){
                    this.removeItem( attrs[0].nodeName );
                }
                this.length = 0;
            },
            key: function(i){
                return attrs[i] ? decode(attrs[i].nodeName) : undefined;
            }
        };
        //提供模擬的"localStorage"接口
        if( !("localStorage" in window) ){
            window.localStorage = LS;            
        }
    })();
    
    //二次包裝接口
    window.LS = !LS ? notSupport : {
        set : function(key, value){
            //fixed iPhone/iPad 'QUOTA_EXCEEDED_ERR' bug
            if( this.get(key) !== undefined )
                this.remove(key);
            LS.setItem(key, value);
            this.length = LS.length;
        },
        //查詢不存在的key時,有的瀏覽器返回null,這裏統一返回undefined
        get : function(key){
            var v = LS.getItem(key);
            return v === null ? undefined : v;
        },
        remove : function(key){ LS.removeItem(key);this.length = LS.length; },
        clear : function(){ LS.clear();this.length = 0; },
        //本地存儲數據遍歷,callback接受兩個參數 key 和 value,若是返回false則終止遍歷
        each : function(callback){
            var list = this.obj(), fn = callback || function(){}, key;
            for(key in list)
                if( fn.call(this, key, this.get(key)) === false ){
                    break;                    
                }
        },
        //返回一個對象描述的localStorage副本
        obj : function(){
            var list={}, i=0, n, key;
            if( LS.isVirtualObject ){
                list = LS.key(-1);
            }else{
                n = LS.length;
                for(; i<n; i++){
                    key = LS.key(i);
                    list[key] = this.get(key);
                }
            }
            return list;
        },
        length : LS.length
    };
    //若是有jQuery,則一樣擴展到jQuery
    if( window.jQuery ) window.jQuery.LS = window.LS;
})(window);

 

使用方法:

存儲方法:

$.LS.set('username', app.username);


獲取方法:

$.LS.get('username');

清空方法:

$.LS.remove("username");

 

 

將全部的字段存儲到一個對象中的須要二次封裝:

/**
 * 本地存儲相關方法對象
 * @type {Object}
 */

var app = app || {};
app.ls = app.ls || {};
(function(){
    var ls = app.ls;
    
  /**
   * 設置本地存儲變量的值
   *
   * 若是有keys和val則先設置app.storage裏面的對應內容;
   * 而後再把app.sotrage轉換成string
   * 最後存入localstorage裏面
   *
   * @param {string} keys 定義一個本地存儲變量
   * @param {*} val  給keys變量賦予的值
   * @return {[type]} [description]
   */
    ls.set = function(keys, val){
        app.storage[keys] = val;
        var v = xue.json.stringify(app.storage);
        $.LS.set('app', v);
    };
    
  /**
   * 獲取本地存儲變量的值
   *
   * 先從localstorage裏面取出app的內容
   * 把取出的內容轉換成JSON
   * 若是有keys返回出對應值,不然返回這個json內容
   *
   * @param  {string} keys 本地存儲的一個變量
   * @return {*}           返回本地存儲中某個變量的值
   */
    ls.get = function(keys){
        var v = $.LS.get('app');
        var val = xue.json.parse(v);
        if(keys && val[keys]){
            return val[keys];
        }else{
            return val;
        }
    };

  /**
   * 刪除本地存儲的某個元素及其值
   * @param  {string} keys 本地存儲的一個變量
   * @return {[type]}      [description]
   */
    ls.remove = function(keys){
        var v = $.LS.get('app');
        if(typeof v != 'string'){
            return;
        }
        var val = xue.json.parse(v);
        if(keys && val[keys]){
            app.storage[keys] = null;
            delete val[keys];
            $.LS.set('app', xue.json.stringify(val));
        }else{
            $.each(app.storage, function(k, m){
                app.storage[k] = null;
            });
            $.LS.remove('app');
        }
    };
})();

 

使用方法:

存儲方法:

app.ls.set('username', app.username);
app.ls.set('userinfo', d.data.userInfo);


獲取方法:

app.ls.get('username');

清空方法:

app.ls.remove();或者app.ls.remove('username');

相關文章
相關標籤/搜索