jQuery的緩存機(jī)制淺析
前不久在研究jQuery的動(dòng)畫隊(duì)列的時(shí)候,發(fā)現(xiàn)jQuery的緩存系統(tǒng)也很強(qiáng)大,盡管以前也稍微接觸過(guò),但一直都沒(méi)有深入研究過(guò)。jQuery的緩存系統(tǒng)在外部應(yīng)用的時(shí)候都比較簡(jiǎn)單,比如要將某個(gè)URL數(shù)據(jù)存到緩存中只要這么寫:
var val = "stylechen.com";
$("div").data( "url" ); // 返回undefined
$("div").data( "url", val ); // 返回"stylechen.com"
$("div").data( "url" ); // 返回"stylechen.com"
不光可以存儲(chǔ)字符串,上面的val也可以是任意數(shù)據(jù),對(duì)象、數(shù)組、函數(shù)等都可以存到里面。僅僅實(shí)現(xiàn)這種功能還是挺簡(jiǎn)單的,聲明一個(gè)全局對(duì)象用來(lái)存儲(chǔ)數(shù)據(jù),然后使用data方法來(lái)存儲(chǔ)或返回?cái)?shù)據(jù):
var cacheData = {}; // 用來(lái)存儲(chǔ)數(shù)據(jù)的全局對(duì)象
var data = function( key, val ){
if( val !== undefined ){
cacheData[key] = val;
}
return cacheData[key];
};
jQuery緩存系統(tǒng)的真正魅力在于其內(nèi)部應(yīng)用中,動(dòng)畫、事件等都有用到這個(gè)緩存系統(tǒng)。之前在寫easyAnim的時(shí)候,我將動(dòng)畫的隊(duì)列都存儲(chǔ)到各DOM元素的自定義屬性中,這樣雖然可以方便的訪問(wèn)隊(duì)列數(shù)據(jù),但也同時(shí)帶來(lái)了隱患。如果給DOM元素添加自定義的屬性和過(guò)多的數(shù)據(jù)可能會(huì)引起內(nèi)存泄漏,所以要盡量避免這么干。
如果是使用jQuery的緩存系統(tǒng)來(lái)存放DOM元素的數(shù)據(jù),會(huì)先給該DOM元素添加一個(gè)隨機(jī)生成的屬性,這個(gè)屬性用來(lái)存放訪問(wèn)緩存數(shù)據(jù)的索引值,就好比DOM元素都有一把開(kāi)啟緩存保險(xiǎn)箱的鑰匙,只要有了鑰匙就可以隨時(shí)開(kāi)啟緩存保險(xiǎn)箱。將本來(lái)存放到DOM元素中的數(shù)據(jù)都轉(zhuǎn)到了緩存中,而DOM元素本身只要存儲(chǔ)一個(gè)簡(jiǎn)單的屬性就可以了,這樣就可以將由DOM元素引起的內(nèi)存泄漏的風(fēng)險(xiǎn)規(guī)避到最小。下面是我模擬jQuery自己寫的一個(gè)簡(jiǎn)單的緩存系統(tǒng):
var cacheData = {}, // 用來(lái)存儲(chǔ)數(shù)據(jù)的全局對(duì)象
uuid = 0,
// 聲明隨機(jī)數(shù)
expando = "cacheData" ( new Date() "" ).slice( -8 );
var data = function( key, val, data ){
if( typeof key === "string" ){
if( val !== undefined ){
cacheData[key] = val;
}
return cacheData[key];
}
else if( typeof key === "object" ){
var index,
thisCache;
if( !key[expando] ){
// 添加一個(gè)DOM元素的屬性
// 隨機(jī)數(shù)是屬性名 索引值是屬性值
index = key[expando] = uuid;
thisCache = cacheData[index] = {};
}
else{
index = key[expando];
thisCache = cacheData[index];
}
if( !thisCache[expando] ){
thisCache[expando] = {};
}
if( <a >gambling</a> data !== undefined ){
// 將數(shù)據(jù)存到緩存對(duì)象中
thisCache[expando][val] = data;
}
// 返回DOM元素存儲(chǔ)的數(shù)據(jù)
return thisCache[expando][val];
}
};
var removeData = function( key, val ){
if( typeof key === "string" ){
delete cacheData[key];
}
else if( typeof key === "object" ){
if( !key[expando] ){
return;
}
// 檢測(cè)對(duì)象是否為空
var isEmptyObject = function( obj ) {
var name;
for ( name in obj ) {
return false;
}
return true;
},
removeAttr = function(){
try{
// IE8及標(biāo)準(zhǔn)瀏覽器可以直接使用delete來(lái)刪除屬性
delete key[expando];
}
catch (e) {
// IE6/IE7使用removeAttribute方法來(lái)刪除屬性
key.removeAttribute(expando);
}
},
index = key[expando];
if( val ){
// 只刪除指定的數(shù)據(jù)
delete cacheData[index][expando][val];
// 如果是空對(duì)象 索性全部刪除
if( isEmptyObject( cacheData[index][expando] ) ){
delete cacheData[index];
removeAttr();
}
}
else{
// 刪除DOM元素存到緩存中的所有數(shù)據(jù)
delete cacheData[index];
removeAttr();
}
}
};
上面的代碼值得注意的是IE6/IE7中用delete來(lái)刪除自定義的屬性會(huì)報(bào)錯(cuò),只能使用removeAttribute來(lái)刪除,標(biāo)準(zhǔn)的瀏覽器都可以使用delete來(lái)刪除。下面是調(diào)用的結(jié)果:
var box = document.getElementById( "box" ),
list = document.getElementById( "list" );
data( box, "myName", "chen" );
alert( data( box, "myName" ) ); // chen
data( box, "myBlog", "stylechen.com" );
alert( data( box, "myBlog" ) ); // stylechen.com
removeData( box, "myBlog" );
alert( data( box, "myBlog" ) ); // undefined
alert( data( box, "myName" ) ); // chen
alert( box[expando] ); // 1
removeData( box );
alert( box[expando] ); // undefined
當(dāng)然,jQuery的緩存系統(tǒng)比我的這個(gè)要復(fù)雜些,不過(guò)核心原理還是一樣的。easyAnim將會(huì)在后續(xù)的版本中引入這個(gè)緩存系統(tǒng)。
- 在localStorage中存儲(chǔ)對(duì)象數(shù)組并讀取的方法
- 詳解JavaScript中l(wèi)ocalStorage使用要點(diǎn)
- android webview 中l(wèi)ocalStorage無(wú)效的解決方法
- JS localStorage實(shí)現(xiàn)本地緩存的方法
- 使用jquery讀取html5 localstorage的值的方法
- Android使用緩存機(jī)制實(shí)現(xiàn)文件下載及異步請(qǐng)求圖片加三級(jí)緩存
- 深入理解Ruby on Rails中的緩存機(jī)制
- PHP緩存機(jī)制Output Control詳解
- 簡(jiǎn)單的php緩存類分享 php緩存機(jī)制
- 移動(dòng)端使用localStorage緩存Js和css文的方法(web開(kāi)發(fā))
- localStorage的黑科技-js和css緩存機(jī)制
相關(guān)文章
jquery入門—數(shù)據(jù)刪除與隔行變色以及圖片預(yù)覽
項(xiàng)目需求:表格中數(shù)據(jù)隔行變色、刪除數(shù)據(jù)、全選刪除、鼠標(biāo)移動(dòng)到圖片時(shí)顯示圖片預(yù)覽等等,感興趣的朋友可以參考下2013-01-01jQuery實(shí)現(xiàn)移動(dòng)端圖片上傳預(yù)覽組件的方法分析
這篇文章主要介紹了jQuery實(shí)現(xiàn)移動(dòng)端圖片上傳預(yù)覽組件的方法,結(jié)合實(shí)例形式分析了jQuery移動(dòng)端圖片上傳預(yù)覽組件的實(shí)現(xiàn)原理、核心代碼與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-05-05jQuery獲得頁(yè)面元素的絕對(duì)/相對(duì)位置即絕對(duì)X,Y坐標(biāo)
jQuery獲得頁(yè)面元素的絕對(duì)X,Y坐標(biāo),可以用offset()方法,下面有個(gè)不錯(cuò)的坐標(biāo)大家可以參考下2014-03-03jQuery Collapse1.1.0折疊插件簡(jiǎn)單使用
這篇文章主要介紹了jQuery Collapse1.1.0折疊插件的使用方法 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08jQuery實(shí)現(xiàn)鼠標(biāo)滑過(guò)圖片移動(dòng)特效
這篇文章主要介紹了jQuery實(shí)現(xiàn)鼠標(biāo)滑過(guò)圖片移動(dòng)特效,鼠標(biāo)移動(dòng)到圖片上時(shí)圖片向上動(dòng)一下,等到鼠標(biāo)離開(kāi)后,圖片又返回到原來(lái)位置,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12移動(dòng)手機(jī)APP手指滑動(dòng)切換圖片特效附源碼下載
這篇文章主要介紹了移動(dòng)手機(jī)APP手指滑動(dòng)切換圖片特效附源碼下載的相關(guān)資料,需要的朋友可以參考下2015-11-11