javascript 緩衝系統

來源:互聯網
上載者:User

模仿jQuery,設計了一個緩衝系統。像jQuery.data這樣的東西,Prototype與mootools也有,目的都是用來輔助事件系統,用來緩衝其中產生的資料,而非緩衝普通函數上次計算的結果。Prototype利用了它的Hash類,mootools沒細看,它內部好像用來緩衝uuid。一個共識是,為頁面用到的元素設定uuid非常有用,要尋找元素時,可以避免重複尋找,也可以用於與事件回呼函數相綁定。由於uuid目前只有IE支援,它叫做uniqueID,格式為ms__id\d+,後面的數字也有名堂,叫做uniqueNumber。jQuery那個算是uniqueNumber吧,而且它的緩衝系統非常複雜,支援緩衝單個資料(利用data這個讀寫方法)與一組資料(利用queue,刪除用dequeue)。沒辦法,因為它是白手起家,沒有像Prototype那樣利用一個自定資料類型分擔一下職責。是時候進入正題,說一下我的緩衝系統了。它利用到我的超級數組對象,實現像queue與dequeue。但我的超級數組對象能做的事更多,像filter,forEach,map,reduce,one,toObject,contains,remove等一應俱全。

   dom.eventTypes = dom.array(String("abort blur change click contextmenu  \                 dblclick error focus  keydown keypress keyup load mousedown  \                 mouseenter mouseup mouseleave mousemove mouseover mouseout \                 reset resize  select submit unload").match(/\w+/g));    //******************************緩衝系統***********************    dom.mixin({        uuid : 0,        storage: {},        buildCache:function(item){            var key,cache = dom.storage;            //如果是window            if ( item.setInterval && ( item !== window && !item.frameElement )) {                key =  "dom-window"            }else if(item.nodeType){                if(!item.uuid){                    item.uuid = "dom" + dom.uuid++                    dom.cache("uuid","uuid-set",item);//儲存元素的引用                }//如果當前元素沒有uuid這屬性,那麼為它添加一個                      key =  item.uuid            }else if(dom.isString(item)){                key =  item;            }else{               throw "item must be element node ,window or string"            }            if(!cache[key]){                cache[key] = {};            }            return cache[key]        },        cache:function(item,name,data){//讀寫緩衝            var cache = dom.buildCache(item);            if(data !== undefined){                if(dom.isFunction(data)){//緩衝函數,在函數設定一個uuid,產生方式取其toString()並去掉空白                    var uuid = (data+"").replace(/\s+/g,'');                    data.uuid = uuid;                }                if(!cache[name]){                    //set與list允許緩衝一組資料,                    //其中如果帶有-set尾碼允許其中的元素重複,list則不允許                    if(/-set$/.test(name)){//如果是第一次儲存                        cache[name] = array(data);                        cache[name].type = "set";                    }else if(/-list$/.test(name)){//                        cache[name] = array(data);                        cache[name].type = "list";                    }else{                        cache[name] = data;                    }                }else{                    var type = cache[name].type;                    if(type && type === "set" ){                        cache[name].ensure(data)                    }else if(type && type === "list" ){                        cache[name].push(data)                    }else{                        cache[name] = data;                    }                }                return item;            }else{                return cache[name]            }        },        //參數可以為1,2,3        removeCache:function(item,name,data){            if(!arguments.length) return;            var cache = dom.buildCache(item),isDOM = !!item.nodeType;            if(isDOM && dom.eventTypes.contains(name)){                name = name + "-handlers-list";            };            if(arguments.length === 3){//移除指定的data                 if(cache[name] instanceof dom.array && cache[name].length > 0){                    //對於由事件綁定函數構成的超級數組,我們在緩衝它的時候為每個函數設定了一個uuid                    //現在我們比較現在傳入的函數的uuid與超級數組中的某個元素的uuid是否相等                    //如果有我們將得它的引用,有了它我們才能使用remove方法移除它。                    if(dom.isFunction(data)){                        var uuid = (data+"").replace(/\s+/g,''),                        fn = cache[name].one(function(fn){                            return fn.uuid == uuid;                        });                        if(fn){                            cache[name].remove(fn);                        }                    }else{                        cache[name].remove(data);                    }                                      if(cache[name].length === 0)                        dom.removeCache(item,name);                }else{                    dom.removeCache(item,name);                }            }else if(arguments.length === 2){//移除條目                delete cache[name]                if(!dom.isExtensible(cache)){                    dom.removeCache(item);                }            }else {                delete cache;                if(isDOM){                    dom.removeCache("uuid","uuid-set",item);                    dom.removeAttr(item,"uuid");                }            }        },        clearCache:function(){            var cache = dom.buildCache("uuid","uuid-set");            if(!cache) return;//如果為空白直接返回            cache.forEach(function(el){                dom.removeAttr(el,"uuid");            });            dom.storage = null;        }    });

buildCache是用於在dom.storage上開闢一個命名空間,cache用於在命名空間儲存各種資料,可以為單個資料,一組資料,一組資料又分為list與set兩種,區別是允許元素是否重複,重複的list相重於jQuery.queue設定的數組。對於window對象的處理,jQuery是在閉包內搞了一個windowData,我則它為在dom.storage開闢了一個名為dom-window的空間。removeCache相當於jQuery.removeData與jQuery.unquere,但功能還要強大,能根據傳入參數的個數選用不同的功能。clearCache則直接刪除所有緩衝。

值得注意的是,在IE中為DOM元素設定私人屬性會引起記憶體流失,所有在頁面unload時需要手動去除它們。各大類庫也是這樣做了,dom.cache("uuid","uuid-set",item)就是用於unload時取出所有設定過uuid的元素,一一去掉其uuid。不過實際上,調用clearCache方法就可以了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.