当前位置: 代码迷 >> JavaScript >> javascript 兑现本地存储
  详细解决方案

javascript 兑现本地存储

热度:223   发布时间:2013-08-01 15:23:18.0
javascript 实现本地存储
我们先完成一个本地存储的DB类。

db = function() {
    var store = window.localStorage, doc = document.documentElement;
    if (!store) {
        doc.style.behavior = 'url(#default#userData)';
    }
    return {
        /**
         * 保存数据
         */
        set : function(key, val, context) {
            if (store) {
                return store.setItem(key, val, context);
            } else {
                doc.setAttribute(key, value);
                return doc.save(context || 'default');
            }
        },
        /**
         * 读取数据
         */
        get : function(key, context) {
            if (store) {
                return store.getItem(key, context);
            } else {
                doc.load(context || 'default');
                return doc.getAttribute(key) || '';
            }
        },
        /**
         * 删除数据
         * @param {Object}
         * @param {Object}
         */
        rm : function(key, context) {
            if (store) {
                return store.removeItem(key, context);
            } else {
                context = context || 'default';
                doc.load(context);
                doc.removeAttribute(key);
                return doc.save(context);
            }
        },
        /**
         * 清空数据
         */
        clear : function() {
            if (store) {
                return store.clear();
            } else {
                doc.expires = -1;
            }
        }
    };
}();


然后我们再写一个简单的ajax函数。


if ( typeof window.XMLHttpRequest === "undefined") {
    window.XMLHttpRequest = function() {
        return new window.ActiveXObject(navigator.userAgent.indexOf("MSIE 5") >= 0 ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
    };
}
ajax = function(uri, options) {
    var httpRequest, httpSuccess, timeout, isTimeout = false, isComplete = false, noop = function() {
    };

    options = {
        method : options.method || "GET",
        data : options.data || null,
        arguments : options.arguments || null,
        http://play.qqq80.com
        onSuccess : options.onSuccess || noop,
        onError : options.onError || noop,
        onComplete : options.onComplete || noop,
        onTimeout : options.onTimeout || noop,
        isAsync : options.isAsync || true,
        timeout : options.timeout ? options.timeout : 30000,
        contentType : options.contentType ? options.contentType : "utf-8",
        type : options.type || "xml"
    };
    uri = uri || "";
    timeout = options.timeout;

    httpRequest = new window.XMLHttpRequest();
    httpRequest.open(options.method, uri, options.isAsync);
    //设置编码集
    httpRequest.setRequestHeader("Content-Type", options.contentType);

    /**
     * @ignore
     */
    httpSuccess = function(r) {
        try {
            return (!r.status && location.protocol == "file:") || (r.status >= 200 && r.status < 300) || (r.status == 304) || (navigator.userAgent.indexOf("Safari") > -1 && typeof r.status == "undefined");
        } catch(e) {
        }
        return false;
    }
    /**
     * @ignore
     */
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState == 4) {
            if (!isTimeout) {
                var o = {};
                o.responseText = httpRequest.responseText;
                o.responseXML = httpRequest.responseXML;
                o.data = options.data;
                o.status = httpRequest.status;
                o.uri = uri;
                o.arguments = options.arguments;
                http://liebiao.ttplay8.cn
                if (httpSuccess(httpRequest)) {
                    if (options.type === "script") {
                        eval.call(window, data);
                    }
                    options.onSuccess(o);

                } else {
                    options.onError(o);
                }
                options.onComplete(o);
            }
            isComplete = true;
            //删除对象,防止内存溢出
            httpRequest = null;
        }
    };

    httpRequest.send(options.data);

    window.setTimeout(function() {
        var o;
        if (!isComplete) {
            isTimeout = true;
            o = {};
            o.uri = uri;
            o.arguments = options.arguments;
            options.onTimeout(o);
            options.onComplete(o);
        }
    }, timeout);

    return httpRequest;
};


好了,最后说一下解决方案,源码如下:


var cacheData = {};
cache = function(url, func, cacheTime) {
    //先读内存
    if(cacheData[url]){
        func.call(this, cacheData[url]);
        return;
    }else{
        var me = this,
        chData = db.get(url),
        chTime = db.get(url + "__time"),
        now = new Date().getTime(),
        cacheTime = cacheTime || 60,
        ct = now - 60000 * cacheTime, //默认缓存时间为1个小时
        success = function(data) {
            var res = data.responseText;
            cacheData[url] = res;
            db.set(url, res);
            db.set(url + "__time", now);
            func.call(me, res);
        };
        //存在数据的情况
        if (chData && chTime) {
            //未过期的情况
            if (ct < chTime) {
                func.call(this, chData);
            } else {//过期的情况
                ajax(url, {'onSuccess' : success});
            }
        } else {
            ajax(url, {'onSuccess' : success});
        }
    }
   
}
javascript开发经验总结【一】:多重条件判断
javascript是一门精巧的语言,可大可小,可伸可缩,如意金箍棒一般,运用恰当,可敌千夫。比如一个场景,有的人要写上百行代码,但是有的人寥寥几笔即可实现,思路就在弹指间。要想学好一门语言,就要掌握其要义,归纳其精髓,方可如鱼得水,运筹帷幄。

js在开发大型组件库的时候经常会碰到很多的逻辑分支情况。比如博客园的编辑框编写:

if(target === "font"){
  someFunction(){...}
}
else if(target === "code"){
  someFunction(){...} 
}
else if(target === "table"){
  someFunction(){...}
}
else if(target === "images"){
  someFunction(){...}
}
else if(target === "link"){
  someFunction(){...} 
}
else if(target === "file"){
  someFunction(){...} 
}


为了逻辑清晰当然也可以这样写:

switch(target){
    case : "font" :
           someFunction(){...}
    break;
    case : "code" :
           someFunction(){...}
    break;
    case : "table" :
           someFunction(){...}
    break;
    case : "images" :
           someFunction(){...}
    break;
    case : "link" :
           someFunction(){...}
    break;
  case : "file" :
           someFunction(){...}
    break;
}

当然这样的一层逻辑很容易书写和维护,但是,如果碰到下面还有多重分支的情况改如何处理呢,大部分人都是继续if else或者switch case。于是代码就变的越来越长,越来越难维护。就像下面的代码一样:

switch(target){
    case : "font" :
           someFunction(){...}
    break;
    case : "code" :
          switch(code){
                 case : "java" :
                       someFunction(){...}
                 break;
                 case : "c" :
                       someFunction(){...}
                 break;
                 case : "c++" :
                       someFunction(){...}
                 break;
          }
        
    break;
    case : "table" :
           someFunction(){...}
    break;
    case : "images" :
           someFunction(){...}
    break;
    case : "link" :
           someFunction(){...}
    break;
  case : "file" :
           someFunction(){...}
    break;
}   


js是一门面向对象的语言,我们能不能用面向对象的思想来解决这个问题呢?请看下面的源码:


editor = {
     "font" : function(){...}
     "code" : function(){...}
     "table" : function(){...}
     "images" : function(){...}
     "file" : function(){...}
}

editor[target]();   


这样是不是清晰明了了很多?而且效率也肯定提升了,因为是对象直接寻址。
大致思路如下:
先创建一个对象,把所有的判断分支都放到这个对象里,然后再调用。

那么是么时候需要用这个方法,什么时候不需要用呢?
先说需要用的:
一、在判断分支很多的情况下建议使用。条理清晰。
二、在分支里的逻辑很复杂的情况下,可以起到逻辑拆分的作用。

再说不需要用的情况:
一、简单的逻辑判断。
二、分支比较少的情况。

  相关解决方案