DIV CSS 佈局教程網

jQuery的緩存機制淺析
編輯:JQuery特效代碼     

前不久在研究jQuery的動畫隊列的時候,發現jQuery的緩存系統也很強大,盡管以前也稍微接觸過,但一直都沒有深入研究過。jQuery的緩存系統在外部應用的時候都比較簡單,比如要將某個URL數據存到緩存中只要這麼寫:
. 代碼如下:
var val = "stylechen.com";
$("div").data( "url" ); // 返回undefined
$("div").data( "url", val ); // 返回"stylechen.com"
$("div").data( "url" ); // 返回"stylechen.com"

不光可以存儲字符串,上面的val也可以是任意數據,對象、數組、函數等都可以存到裡面。僅僅實現這種功能還是挺簡單的,聲明一個全局對象用來存儲數據,然後使用data方法來存儲或返回數據:

. 代碼如下:
var cacheData = {}; // 用來存儲數據的全局對象
var data = function( key, val ){
 if( val !== undefined ){
  cacheData[key] = val;
 }

 return cacheData[key];
}; 

jQuery緩存系統的真正魅力在於其內部應用中,動畫、事件等都有用到這個緩存系統。之前在寫easyAnim的時候,我將動畫的隊列都存儲到各DOM元素的自定義屬性中,這樣雖然可以方便的訪問隊列數據,但也同時帶來了隱患。如果給DOM元素添加自定義的屬性和過多的數據可能會引起內存洩漏,所以要盡量避免這麼干。

如果是使用jQuery的緩存系統來存放DOM元素的數據,會先給該DOM元素添加一個隨機生成的屬性,這個屬性用來存放訪問緩存數據的索引值,就好比DOM元素都有一把開啟緩存保險箱的鑰匙,只要有了鑰匙就可以隨時開啟緩存保險箱。將本來存放到DOM元素中的數據都轉到了緩存中,而DOM元素本身只要存儲一個簡單的屬性就可以了,這樣就可以將由DOM元素引起的內存洩漏的風險規避到最小。下面是我模擬jQuery自己寫的一個簡單的緩存系統:
. 代碼如下:
var cacheData = {}, // 用來存儲數據的全局對象
 uuid = 0,
 // 聲明隨機數
 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] ){
   // 添加一個DOM元素的屬性
   // 隨機數是屬性名 索引值是屬性值
   index = key[expando] = uuid;
   thisCache = cacheData[index] = {};
  }
  else{
   index = key[expando];
   thisCache = cacheData[index];
  }

  
  if( !thisCache[expando] ){
   thisCache[expando] = {};
  }

  if( <a href="http://jb51.net">gambling</a> data !== undefined ){
   // 將數據存到緩存對象中
   thisCache[expando][val] = data;
  }

  // 返回DOM元素存儲的數據
  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及標准浏覽器可以直接使用delete來刪除屬性
     delete key[expando];
    }
    catch (e) {
     // IE6/IE7使用removeAttribute方法來刪除屬性
     key.removeAttribute(expando);
    }
   },

   index = key[expando];

  if( val ){
   // 只刪除指定的數據
   delete cacheData[index][expando][val];
   // 如果是空對象 索性全部刪除
   if( isEmptyObject( cacheData[index][expando] ) ){
    delete cacheData[index];
    removeAttr();
   }
  }
  else{
   // 刪除DOM元素存到緩存中的所有數據
   delete cacheData[index];
   removeAttr();
  }
 }
};


上面的代碼值得注意的是IE6/IE7中用delete來刪除自定義的屬性會報錯,只能使用removeAttribute來刪除,標准的浏覽器都可以使用delete來刪除。下面是調用的結果:

. 代碼如下:
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

當然,jQuery的緩存系統比我的這個要復雜些,不過核心原理還是一樣的。easyAnim將會在後續的版本中引入這個緩存系統。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved