jQuery的緩存機(jī)制淺析
前不久在研究jQuery的動(dòng)畫隊(duì)列的時(shí)候,發(fā)現(xiàn)jQuery的緩存系統(tǒng)也很強(qiáng)大,盡管以前也稍微接觸過,但一直都沒有深入研究過。jQuery的緩存系統(tǒng)在外部應(yīng)用的時(shí)候都比較簡單,比如要將某個(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ù),對象、數(shù)組、函數(shù)等都可以存到里面。僅僅實(shí)現(xiàn)這種功能還是挺簡單的,聲明一個(gè)全局對象用來存儲(chǔ)數(shù)據(jù),然后使用data方法來存儲(chǔ)或返回?cái)?shù)據(jù):
var cacheData = {}; // 用來存儲(chǔ)數(shù)據(jù)的全局對象
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元素的自定義屬性中,這樣雖然可以方便的訪問隊(duì)列數(shù)據(jù),但也同時(shí)帶來了隱患。如果給DOM元素添加自定義的屬性和過多的數(shù)據(jù)可能會(huì)引起內(nèi)存泄漏,所以要盡量避免這么干。
如果是使用jQuery的緩存系統(tǒng)來存放DOM元素的數(shù)據(jù),會(huì)先給該DOM元素添加一個(gè)隨機(jī)生成的屬性,這個(gè)屬性用來存放訪問緩存數(shù)據(jù)的索引值,就好比DOM元素都有一把開啟緩存保險(xiǎn)箱的鑰匙,只要有了鑰匙就可以隨時(shí)開啟緩存保險(xiǎn)箱。將本來存放到DOM元素中的數(shù)據(jù)都轉(zhuǎn)到了緩存中,而DOM元素本身只要存儲(chǔ)一個(gè)簡單的屬性就可以了,這樣就可以將由DOM元素引起的內(nèi)存泄漏的風(fēng)險(xiǎn)規(guī)避到最小。下面是我模擬jQuery自己寫的一個(gè)簡單的緩存系統(tǒng):
var cacheData = {}, // 用來存儲(chǔ)數(shù)據(jù)的全局對象
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ù)存到緩存對象中
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;
}
// 檢測對象是否為空
var isEmptyObject = function( obj ) {
var name;
for ( name in obj ) {
return false;
}
return true;
},
removeAttr = function(){
try{
// IE8及標(biāo)準(zhǔn)瀏覽器可以直接使用delete來刪除屬性
delete key[expando];
}
catch (e) {
// IE6/IE7使用removeAttribute方法來刪除屬性
key.removeAttribute(expando);
}
},
index = key[expando];
if( val ){
// 只刪除指定的數(shù)據(jù)
delete cacheData[index][expando][val];
// 如果是空對象 索性全部刪除
if( isEmptyObject( cacheData[index][expando] ) ){
delete cacheData[index];
removeAttr();
}
}
else{
// 刪除DOM元素存到緩存中的所有數(shù)據(jù)
delete cacheData[index];
removeAttr();
}
}
};
上面的代碼值得注意的是IE6/IE7中用delete來刪除自定義的屬性會(huì)報(bào)錯(cuò),只能使用removeAttribute來刪除,標(biāo)準(zhǔn)的瀏覽器都可以使用delete來刪除。下面是調(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ù)雜些,不過核心原理還是一樣的。easyAnim將會(huì)在后續(xù)的版本中引入這個(gè)緩存系統(tǒng)。
- 在localStorage中存儲(chǔ)對象數(shù)組并讀取的方法
- 詳解JavaScript中l(wèi)ocalStorage使用要點(diǎn)
- android webview 中l(wèi)ocalStorage無效的解決方法
- JS localStorage實(shí)現(xiàn)本地緩存的方法
- 使用jquery讀取html5 localstorage的值的方法
- Android使用緩存機(jī)制實(shí)現(xiàn)文件下載及異步請求圖片加三級緩存
- 深入理解Ruby on Rails中的緩存機(jī)制
- PHP緩存機(jī)制Output Control詳解
- 簡單的php緩存類分享 php緩存機(jī)制
- 移動(dòng)端使用localStorage緩存Js和css文的方法(web開發(fā))
- localStorage的黑科技-js和css緩存機(jī)制
相關(guān)文章
基于jquery的一行代碼輕松實(shí)現(xiàn)拖動(dòng)效果
寫JS實(shí)現(xiàn)拖動(dòng)需要一大堆不便維護(hù)的代碼,實(shí)屬麻煩,Google了大半天,發(fā)現(xiàn)了一個(gè)優(yōu)秀的Jquery插件EasyDrag,只需要一行代碼便可輕松在主流瀏覽器上。2010-12-12
jQuery+CSS3實(shí)現(xiàn)仿花瓣網(wǎng)固定頂部位置帶懸浮效果的導(dǎo)航菜單
這篇文章主要介紹了jQuery+CSS3實(shí)現(xiàn)仿花瓣網(wǎng)固定頂部位置帶懸浮效果的導(dǎo)航菜單,可實(shí)現(xiàn)頁面向下滑動(dòng)后導(dǎo)航欄橫向懸浮并固定在頂部的功能,涉及jQuery事件響應(yīng)及頁面元素屬性動(dòng)態(tài)修改相關(guān)操作技巧,需要的朋友可以參考下2016-09-09
jQuery 復(fù)合選擇器應(yīng)用的幾個(gè)例子
這篇文章主要介紹了jQuery 復(fù)合選擇器應(yīng)用的幾個(gè)例子,本文例子所引用的jQuery版本為 jQuery-1.8.3.min.js,喜歡的朋友可以學(xué)習(xí)下2014-09-09
jQuery中attr()與prop()函數(shù)用法實(shí)例詳解(附用法區(qū)別)
這篇文章主要介紹了jQuery中attr()與prop()函數(shù)用法,結(jié)合實(shí)例形式詳細(xì)分析了attr()與prop()函數(shù)的使用技巧與相關(guān)注意事項(xiàng),并附帶了attr()與prop()函數(shù)用法的區(qū)別,需要的朋友可以參考下2015-12-12
jquery 插件實(shí)現(xiàn)瀑布流圖片展示實(shí)例
本文給大家分享的是使用jQuery的masonry庫和infinitescroll庫實(shí)現(xiàn)的瀑布流美女圖片展示的實(shí)例,效果非常不錯(cuò),這里推薦給大家,有需要的小火把可以參考下。2015-04-04
jQuery實(shí)現(xiàn)動(dòng)態(tài)控制頁面元素的方法分析
這篇文章主要介紹了jQuery實(shí)現(xiàn)動(dòng)態(tài)控制頁面元素的方法,結(jié)合實(shí)例形式分析了jQuery事件響應(yīng)及頁面元素動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-12-12
jQuery實(shí)現(xiàn)簡單的網(wǎng)頁換膚效果示例
這篇文章主要介紹了jQuery實(shí)現(xiàn)簡單的網(wǎng)頁換膚效果,涉及jQuery事件響應(yīng)及頁面元素屬性動(dòng)態(tài)變換操作技巧,需要的朋友可以參考下2016-09-09

