`
__游乐场
  • 浏览: 2760 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

jquery1.42 缓存系统分析

阅读更多
  对jquery1.42的源码分析完成一半, 发一段试试水.


                              缓存系统

  在实际应用中, 我们经常需要往节点中缓存一些数据. 这些数据往往和dom元素紧密相关. dom节点也是对象, 所以我们可以直接扩展dom节点的属性. 不过肆意污染dom节点是不良少年的行为. 我们需要一种低耦合的方式让dom和缓存数据能够联系起来.

  jquery提供了一套非常巧妙的缓存办法.

  我们先在jquery内部创建一个cache对象{}, 来保存缓存数据.

  然后往需要进行缓存的dom节点上扩展一个值为expando的属性, 这里是”jquery” + (new Date).getTime().

  接着把每个节点的dom[expando]的值都设为一个自增的变量id,保持全局唯一性.
这个id的值就作为cache的key用来关联dom节点和数据.
也就是说cache[id]就取到了这个节点上的所有缓存.

  而每个元素的所有缓存都被放到了一个map里面,这样可以同时缓存多个数据.

  比如有2个节点dom1和dom2, 它们的缓存数据在cache中的格式应该是这样
  cache = {
	dom1的id: {
		key1: value1,
		key2: value2
         },
        dom2的id: {
	        key3: value3,
	        key4: value4
         }
 }


  expando的值等于”jquery”+当前时间, 元素本身具有这种属性而起冲突的情况是微乎其微的.

  我们在看源码之前, 先根据上面的原理来自己实现一个简单的缓存系统.以便增强理解.

  先把跟data相关的所有代码都封装到一个闭包里,通过返回的接口暴露给外界.
同时为了简便,我们拆分成setData和getData两个方法.

  <div id="ddd">dddddddd</div>

<script>

  var Data = function(){
	var cache = {};
	var expando = "zengtan" + +new Date;
	var uuid = 1;
	
	var setData = function(elem, key, value){
			var id = elem[expando];
			if (!id){   //第一次给元素设置缓存
				id = ++uuid;
				elem[expando] = id;
			}
			if (!cache[id]){   //这个元素第一次进行缓存或者缓存已被清空
				cache[id] = {};
			}
			cache[id][key] = value;
	};

	var getData = function(elem, key){
		var id = elem[expando];  //取得cache里跟dom节点关联的key
		return cache[id] && cache[id][key] || null;  //如果缓存里没有, 返回null
	}

	return {
		setData: setData,
		getData: getData	
	}
  }()


  var div = document.getElementById("ddd");
  Data.setData(div, "name", "zengtan");
  var value = Data.getData(div, "name");
  alert (value)

</script>



看看源码实现.

首先声明一些特殊的节点, 在它们身上存属性的时候可能会抛出异常.
 noData: {
		"embed": true,
		"object": true,
		"applet": true
}

jquery.data

data: function( elem, name, data ) {  		
if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {   
//如果是上面几个noData的节点类型
		return;
	}

	elem = elem == window ?  
        //处理elem是window的情况, 如果不单独处理的话, 等于增加了一个全局变量, windowData也是一个{}
		windowData :
		elem;

		var id = elem[ expando ], cache = jQuery.cache, thisCache;   
                   /*
                    因为存数据的时候, 会给elem[ expando ]   设置一个全局唯一标志量. 判断id是否为     undefined, 就知道已经有没有往这个元素上缓存过数据. 
                   */
		if ( !id && typeof name === "string" && data === undefined ) {   
                //如果没有缓存, 而现在又是get方式. 返回null
			return null;
		}

		if ( !id ) {  
                //第一次进行缓存, 分配一个全局唯一标志id
			id = ++uuid;
		}

		if ( typeof name === "object" ) {  //如果key是对象类型
			elem[ expando ] = id;    //分配id
			thisCache = cache[ id ] = jQuery.extend(true, {}, name); 
			/*把整个对象做为cache[ id ]的值储存, 比如
			    $('#ddd').data({
 				"v2": "bbb",
 				"v3": "ccc"
 			    });
 			    相当于$('#ddd').data("v2", "bbb").data("v3":"ccc");
 			    不过这样会清空该元素以前的data, 不理解为什么要这样做.
 			    觉得这样才是更好的处理
 			    jQuery.extend(cache[ id ], name);
 			*/
		} else if ( !cache[ id ] ) { 
                   //如果cache[ id ]中没有, 表示这个元素第一次进行缓存或者缓存已被清空
			elem[ expando ] = id;
			cache[ id ] = {};  
                        //把cache[ id ]设置为一个map.
		}

		thisCache = cache[ id ];

		if ( data !== undefined ) {     
              /*
              set操作, 也可以防止一些意外的情况下缓存被清空. 比如data未定义的情况下, 缓存操作是无效的.
			var a = {};
			var b;
			$(a).data("c", 3);
			$(a).data("c", b); b为undefined. 这句是无效的. 要移除缓存可以用removeData方法.
               */
			thisCache[ name ] = data;  
               //即cache[ id ][ name ] = data, 把data设置进cache缓存对象中, 前面分配的自增id当做key来关联
		}

		return typeof name === "string" ? thisCache[ name ] : thisCache;  
               //如果key是string类型, 返回key对应的缓存, 否则返回整个元素上的缓存
	}

  理论上讲, data方法可以用于任何对象的缓存, 不过如果是本地对象, 在内存泄露和继承的问题上都会遇到麻烦, 这里不详述, 所以一般我们还是用于dom节点.

  我们用jquery缓存系统的时候, 一般调用的是prototype方法, prototype方法除了调用上面的静态方法之外. 还加入了对节点上自定义事件的处理, 留在event部分再讲.

  当然, 我们还需要删除缓存的方法. 现在看看removeData的代码
Jquery.removeData

removeData: function( elem, name ) {
		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {    //同data方法
			return;
		}

		elem = elem == window ?
			windowData :
			elem;   //同data方法

		var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];

		if ( name ) {         //如果有指定的key
			if ( thisCache ) {  //如果元素有缓存
				delete thisCache[ name ];  //直接delete掉
				if ( jQuery.isEmptyObject(thisCache) ) {    
                       //如果thisCache是个空对象, 说明所有缓存的数据都已经被删掉了.
					jQuery.removeData( elem );  
                           /*
                              重新调用一次removeData方法, 删掉缓存系统里已经无用的东西,
                              防止内存泄露, 注意现在走的是下面else分支.
                           */
				}
			}

		} else {
			if ( jQuery.support.deleteExpando ) {  
                           //如果支持delete, 见特性检测部分.
				delete elem[ jQuery.expando ];   //删掉元素的expando属性
			} else if ( elem.removeAttribute ) {   
                           //如果支持removeAttribute
				elem.removeAttribute( jQuery.expando );
			}

			delete cache[ id ];   //全局缓存里删除以这个id为key的对象
		}
	}
});
分享到:
评论
3 楼 zqp_xp 2010-12-09  
分析得不怎么样?明明是 javascript,你却在前贴java,让人以为是java代码.
2 楼 zqp_xp 2010-12-09  
分析得不怎么样?明明是 javacript,你却在前贴java,让人以为是java代码.
1 楼 dimingchan 2010-11-26  
很不错的例子,我现在哟阿修改一个电子商务网站的某个小板块。

相关推荐

    jquery 1.42 帮助文档

    jquery 1.42 帮助文档jquery 1.42 帮助文档jquery 1.42 帮助文档

    jquery1.42.js

    jquery1.42.js

    jquery1.42和api

    **jQuery 1.4.2 和 API 知识详解** jQuery 是一个广泛使用的JavaScript库,它极大地简化了HTML文档遍历、事件处理、动画以及Ajax交互。jQuery 1.4.2 是该库的一个版本,发布于2010年,尽管现在已经有更新的版本,但...

    jquery1.42包括提示功能

    包括4个文件jquery-1.4.2.js(jquery普通),jquery-1.4.2.min.js (jquery-mini), jquery-1.4.2-vsdoc.js(jquery代码提示),jquery.cookie.js (jquery-cookie包)

    Jquery1.42

    jQuery是JavaScript库的一个重要版本,它极大地简化了JavaScript的DOM操作、事件处理、动画制作以及Ajax交互。在本文中,我们将深入探讨jQuery 1.4.2这一特定版本中的核心特性、改进和优化。 首先,jQuery 1.4.2是...

    jquery1.42

    《jQuery 1.4.2:深入解析与应用》 jQuery,这个JavaScript库,自2006年发布以来,以其简洁的API和强大的功能深受开发者喜爱。在本文中,我们将深入探讨jQuery 1.4.2这一经典版本,了解其核心特性、改进和在实际...

    Jquery API 1.4(中文)+ Jquery 1.42

    《jQuery API 1.4(中文)》及jQuery 1.4.2详解 jQuery,一个广泛应用于Web开发的JavaScript库,以其简洁易用的API和强大的功能深受开发者喜爱。本指南将深入探讨《jQuery API 1.4(中文)》及jQuery 1.4.2版本中的...

    jquery 1.42.js && 开发文档

    《jQuery 1.4.2.js与开发文档详解》 jQuery,这个JavaScript库自2006年发布以来,就以其简洁的API和强大的功能深受开发者喜爱。在本篇文章中,我们将深入探讨jQuery 1.4.2.js版本及其相关的开发文档,帮助你更好地...

    清除Jquery缓存

    在探讨“清除Jquery缓存”的话题之前,我们先来了解一下jQuery是什么以及为什么需要清除缓存。 ### jQuery简介 jQuery是一款流行的JavaScript库,它极大地简化了HTML文档的遍历、事件处理、动画以及Ajax交互等操作...

    jQuery缓存性能分析比较案例

    本文将深入探讨jQuery中的缓存性能分析,并通过具体的案例进行比较。 一、jQuery缓存简介 jQuery提供了一个便利的功能,即`$(selector)`,用于选取DOM元素。然而,每次调用此函数都会执行一次DOM查询,这在页面...

    JQuery1.4.1类库,JQuery1.4.2类库和帮助文档

    jQuery是JavaScript的一个强大的库,它极大地简化了网页的DOM操作、事件处理、动画设计和Ajax交互。这个压缩包包含了jQuery1.4.1和1.4.2两个版本的类库,以及相应的帮助文档,旨在为开发者提供更稳定、更高效的选择...

    jquery最全的版本,从1.32~~1.7.1 应有尽有

    接着,到了1.42,jQuery对AJAX进行了大量的改进,支持JSONP跨域请求,这对于Web应用程序的数据获取能力有了显著提升。此外,1.42还增强了动画效果,使得过渡和动画更为平滑。 在1.44版本中,jQuery修复了一些已知的...

    jQuery数据缓存用法分析

    jQuery数据缓存是一种高效的方法,用于在DOM元素上存储和检索数据,同时避免了JavaScript中的内存泄漏问题,尤其是与DOM元素绑定时常见的循环引用风险。本文将深入探讨jQuery的`data()`方法及其相关使用规范。 一、...

    JQuery1.4.2(jquery-1.4.2.js jquery-1.4.2.min.js jquery-1.4.2-vsdoc.js jquery-1.4.2-vsdoc_en.js jquery.cookie.js)

    jquery-1.4.2.js jquery-1.4.2.min.js jquery-1.4.2-vsdoc.js 中文版vsdoc jquery-1.4.2-vsdoc_en.js jquery.cookie.js

    jquery-1.4.2.min.js

    最新在做ActiveMQ Web端开发时,发现这个官方给出的ajax测试例子里用到这个js插件, 就在这里免积分贡献了。

    jquery库1.42

    jQuery的生态系统包含了众多插件,如jQuery Validation用于表单验证,jQuery ScrollTo实现页面滚动,jQuery Masonry实现瀑布流布局等。这些插件扩展了jQuery的功能,满足了各种复杂需求。 在JQuery库最新版中,可能...

    jquery1.4中文手册(CHM)

    **jQuery 1.4中文手册**是一份专为开发者准备的详尽教程,它以CHM(Compiled Help Manual)格式提供,便于离线查阅。这个手册涵盖了jQuery库1.4版本的所有核心功能和API,是学习和理解jQuery的宝贵资源。 jQuery是...

    jQuery:图片缓存 10 jQuery Image Cache Plugins and Scripts

    **jQuery 图片缓存插件与脚本** 在网页设计中,图片的加载速度往往对用户体验有着重大影响。当用户浏览网页时,如果图片加载缓慢,可能会导致页面显得卡顿,影响用户对网站的整体评价。为了解决这个问题,开发者...

    jQuery最新类库1.4.2min_UI库1.8.4.custom.min及中文版API

    6. **插件系统**:jQuery允许开发者创建和分享自己的插件,扩展其功能,满足更多特定需求。 7. **链式操作**:jQuery的API设计支持链式调用,如`$("#element").css("color", "red").fadeIn(500)`,提高了代码的...

Global site tag (gtag.js) - Google Analytics