JavaScript编程开发中jQuery的缓存机制浅析
前不久在研究jquery的动画队列的时候,发现jquery的缓存也很强大,尽管以前也稍微接触过,但一直都没有深入研究过。jquery的缓存系统在外部应用的时候都比较简单,比如要将某个url数据存到缓存中只要这么写:
. 代码如下:
var val = "stylechen.com";
$("p").data( "url" ); // 返回undefined
$("p").data( "url", val ); // 返回"stylechen.com"
$("p").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="https://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将会在后续的版本中引入这个缓存系统。
推荐阅读
-
JavaScript编程开发中jQuery的缓存机制浅析
-
JavaScript编程开发中基于jQuery的视频播放插件开发教程
-
JavaScript开发中利用jQuery将多条数据插入模态框的示例代码
-
JavaScript编程开发中jquery获取radio值实例教程
-
JavaScript编程开发中如何使用jquery实现放大镜效果
-
JavaScript开发中14个有用的Jquery技巧分享
-
JavaScript编程开发中jquery搜索框效果实现方法
-
JavaScript编程开发中jquery常用操作小结
-
JavaScript编程开发中jquery中post方法用法实例教程
-
JavaScript编程开发中jquery.cookie.js使用指南