手机版

介绍jQuery对象数据缓存的原理和jQuery.data方法的区别

时间:2021-11-22 来源:互联网 编辑:宝哥软件园 浏览:

有很多在线老师教你如何使用jQuery.data(.)来实现数据缓存。但是,有两个用户经常使用数据([key],[value])和jquery.data (element,[key],[value])。几乎没有文章阐明它们之间的区别,所以我使用它们,并在研究后与您分享。$(' ')之间的差异。数据([键]、[值])和jQuery。数据(element、[key]、[value])这两个函数用于存储元素上的数据,也就是说,它们通常被称为数据缓存,它们都返回jquery对象。当时分别使用的时候,真的很震惊。差别相当大。我真的不需要知道。先看例子,然后根据源代码进行分析。代码:复制的代码如下: div id=' test 2 ' onclick=' test()' test 2/div id=' abc3 ' onclick=' test()' test 3/div id=' test ' onclick=' test()' test/div p id=' TTT ' AAAA/p script $(文档)。ready(function(){ $('#test '))。单击(function(){ alert(' JQUERY '));var e=$(' div ');//定义了两个jquery对象var w=$(' div ');//e不等于W.//首先使用数据([key],[value])。$(e)。数据(' a ',' AAAA ');//分别在e和w上保存与Key相同的数据,$(w)。数据(' a ',' wwww ');//查看它是否会覆盖前一个,尽管它保存在不同的对象上。警报($(e)。数据(' a ');//你猜到答案了吗?输出为wwwwww。是不是有点出乎意料?alert(e===w)//false alert($(w)。数据(' a ');//这也是wwww//使用jquery.data (element、[key]、[value])存储数据。$.数据(e,' b ',' cccc ');//分别在e和w上保存与Key相同的数据,$。数据(w,' b ',' dddd ');//查看它是否会覆盖前一个,尽管它保存在不同的对象上。警报($。数据(e,' b ');//你应该能猜出答案。输出cccalert ($。数据(w,' b ');//此输出dddd });});/script看完上面的例子,有没有发现data([key],[value])和jquery.data (element,[key],[value])完全不一样?他们之间有什么关系吗?为什么数据([键],[值])会覆盖与上一个键相同的值?而jquery.data(元素、[键]、[值])只要绑定到不同的对象就不会导致覆盖。是这样吗?让我们研究一下它们的源代码。先看看jquery.data(元素、[键]、[值])的源代码。Js的代码:复制的代码如下: jquery . extend({ cache : },//请谨慎使用uuid 33600,//对于页面上的每个jQuery副本都是唯一的//删除非数字以匹配rinlinejQuery expando : ' jQuery '(jQuery . fn . jQuery math . random())。替换(/\ d/g ' '),data:函数(elem,name,data,PVT/*仅供内部使用*/){//如果可以附加数据,如果不能,直接返回if(!jquery . accept data(elem)){ return;} var private cache,this cache,ret,//jquery.expando这是一个唯一的字符串,它是在生成jquery对象时生成的。Internalkey=jquery.expando,getbyname=type类型==' string '。//有必要区别对待DOM元素和JS对象,因为IE6-7不能跨DOM对象和JS对象垃圾收集对象的引用属性isNode=elem.nodeType。//如果是DOM元素,使用全局jquery . cache .//如果是JS对象,直接附加到对象上。cache=isNode?jQuery.cache : elem,//只有当JS对象的缓存已经存在时,才为其定义一个ID,这样就允许//代码在与没有缓存id=isNode的DOM节点相同的路径上进行快捷操作?elem[internal key]: elem[internal key]internal key,isEvents=name===' events//避免做更多不必要的工作。当您试图从没有任何数据的对象中获取数据时,//该对象没有数据,因此您可以直接返回if((!id ||!缓存[id] ||(!isEvents!pvt!缓存[id]。data))getByName data===undefined){ return;} //id id不存在,生成一个if(!id ) { //由于其数据//最终在全局缓存if (isNode ) { //如果是DOM元素,则在元素上生成唯一的id,并以jQuery.expando //为属性值保存在elem元素上,以便以后根据jQuery.expando查找ID。

elem[InternAlKey]=id=jquery。uuid} else { //JS对象则直接使用jQuery.expando,既然是直接附加到对象上,又何必要编号呢?//避免与其他属性冲突!id=internalKey} } ////当我们试着访问一个键是否含有值的时候,如果不存在jQuery.cache[id]值, //初始化jQuery.cache[id]值为一个空对象{} if(!cache[id]){ cache[id]={ };if(!isNode){ 0缓存[ id ].toJSON=jQuery.noop} } //可以将对象传递给jQuery.data,而不是键/值对;这会将//浅层复制到现有的缓存//数据中是接收对象和函数,浅拷贝if(类型为name==' object ' | |类型为name==' function '){ if(PVT){ cache[id]=jquery。extend(缓存[id],名称);} else { cache[ id ].data=jQuery.extend(缓存[ id ].数据、名称);} }/存储对象,存放了所有数据的映射对象privateCache=thisCache=缓存[id];//jQuery数据()存储在对象内部数据//缓存内部的单独对象中,以避免内部数据和用户定义的//数据之间的键冲突//jQuery .内部数据存在一个独立的对象(这个缓存。data==此缓存[internalKey])//上,为了避免内部数据和用户定义数据冲突if(!pvt ) { //存放私有数据的对象不存在,则创建一个{} if(!这个缓存。数据){此缓存。数据={ };} //使用私有数据对象替换这个缓存这个缓存=这个缓存。数据;} //如果数据不是未定义,表示传入了数据参数,则存储数据到名字属性上如果(数据!==未定义){ //jQuery.camelCase(名称)作用是如果传入的是对象/功能,不做转换, //只有传入的名字是字符串才会转换。所以最终保存下来的是密钥/值对;这个缓存[jquery。camelcase(名称)]=数据;} //从这以后下面的代码都是处理数据:函数(elem,名称)数据为空,求返回值数据的情况了如果(isEvents!此缓存[名称]){返回私有缓存。事件;} //如果名字是字符串,则返回数据/如果不是,则返回整个存储对象if (getByName ) { //首先尝试查找原样属性数据ret=此缓存[名称];//测试null未定义的属性数据if (ret==null ) { //尝试查找camelCase属性ret=此缓存[jquery。camelcase(名称)];} } else { ret=thisCache}返回ret},.});请看图

看jQuery.data(元素、[键]、[值])源代码后可以知道,每一个元素都会有自己的一个{key:value}对象保存着数据,所以新建的对象就算有键相同它也不会覆盖原来存在的对象键所对应的价值,因为新对象保存是是在另一个{key:value}对象中。接下来要分析数据([键]、[值])源代码使用到了每个(回调),在分析它之前先看下每个(回调)用法和源代码Js。代码:复制代码代码如下: div id=' test 2 ' onclick=' test()' test 2/div id=' abc3 ' onclick=' test()' test 3/div id=' test ' onclick=' test()' test/div p id=' TTT ' AAAA/p脚本$(文档)。ready(function(){ $('#test ')).单击(function(){ alert(' JQUERY ');var I=0;$('#abc3 ').每个(函数(){ alert(I);//只输出1;因为只有一个div id=' abc3 ' });alert('-');var j=0;$(“div”).每个(函数(){ alert(j));//分别输出1,2,3;因为有三个差异所以循环三遍});});});/script现在来看每个方法的具体实现如下:jquery。fn=jquery。prototype={每个:函数(回调,args ) { return jQuery.each(this,回调,args);} } 可以看到它返回的是全局的每个方法,并且将自身jQuery对象做为参数给它,全局的每个方法的具体实现如下://args作为内部成员的调用来使用每个:函数(对象、回调args ) { var name,i=0,length=object.length//当目标为jQuery对象时,长度非空if(args){ if(length===undefined){ for(对象中的名称)if(回调。apply(object[name],args)==false)break;} else for(;一、长度;)if (callback.apply(object[ i ],args)==false)break;//以下是客户端程序进行调用} else { if(length===undefined){ for(对象中的名称)if(回调。call(object[name],name,object[name])===false)break;} else //i表示索引值,值表示数字正射影像图元素用于(var值=对象[0];我长度回调。调用(值,我,值)!==falsevalue=object[ i] ){} }返回对象;} 现在我们关注下用于(var值=对象[0];我长度回调。调用(值,我,值)!==falsevalue=object[ i] ){}这句代码;其中对象[0]取得jQuery对象中的第一个数字正射影像图元素,通过为循环,得到遍历整个jQuery对象中对应的每个数字正射影像图元素,通过callback.call(value,I,value);将回收的这对象指向价值对象,并且传递两个参数,我表示索引值,值表示数字正射影像图元素;其中回收是类似于函数(索引,elem) { }的方法。所以就得到$('').每个(函数(index,elem){ });再来看看数据([键]、[值])的源代码射流研究…代码:复制代码代码如下: jquery。fn。extend({ data : function(key,value ) { var parts,part,attr,name,l,elem=this[0],i=0,data=null//如果(键===未定义){则获取所有值.//处理没有钥匙的情况,这里不是我们要讨论的返回数据;} //设置多个值if(键的类型==' object '){返回这个。每个(函数(){ jquery。数据(this,key));});} parts=key.split(' . 2 );零件[1]=零件[1]?零件[1]:"";part=parts[1]'!返回jQuery.access(this,function(value){ if(value===undefined)}。/.这里是没有价值时,是索取返回值的情况,这不是我们讨论}零件[1]=值;//如果我使用用$(“div”).数据(' a ',' aaa '),下面调用每个前的这指的是$(“div”)这返回的对象,this.each(function() {//注意了,这里是以每一个匹配的元素作为上下文来执行一个函数var self=jQuery(this);self.triggerHandler('setData ')部分,零件);//这里在元素上存放数据,本质还是委托数据(元素、[键]、[值])来做的。 //看前面有分析过了。 //下面数据(这个、键、值)里的这指的是遍历整个jQuery对象中对应的每个数字正射影像图元素//$(“div”)它对应页面中一个差异数组。

jQuery.data(this,key,value)span style=' background-color : # ffcc 00;';//这句话会反复执行,也就是保存数据/span。//这是核心句。但要看清楚上面,是在每一个(funcipn () {})里面。self . triggerhandler(' changeData '部分,parts);});},null,value,arguments.length 1,null,false);},//移除元素上存储的数据。实现如下:removedata:函数(键){返回此。每个(函数(){jquery。removedata(此,键);});} });如果你不太了解数据的源代码([key],[value]),好的,我就用一个例子来模仿一下。代码:复制的代码如下: div id=' test 2 ' onclick=' test()' test 2/div id=' abc3 ' onclick=' test()' test 3/div id=' test ' onclick=' test()' test/div p id=' TTT ' AAAA/p script $(文档)。ready(function(){ $('#test '))。单击(function(){ alert(' JQUERY '));var I=0;$('#abc3 ')。每个(函数(){ alert(I);//仅输出1;只有一个div id=' abc3 ' });alert('-');var j=1;$(“div”)。每个(函数(){//执行这个函数$。每个匹配元素作为上下文的数据(这是“a”、“wwww”);//这里的意思是$('div ')。//分别遍历每个匹配的元素,并为每个对象{}保存一个键/值警告(j)。//分别输出1、2、3,因为有三个div元素});警报($('#test ')。数据(' a ');//返回wwwwww。//你惊讶吗?我没有保存在上面,但是有价值。很明显,是检查这个div节点上是否有值。//必须有一个值,因为上面是循环保存在Dom节点div上的。alert($(“# test”)===$(“div”));//false证明两个新创建的对象不一样。警报($(“div”)。数据(' a ');//返回wwwwww。//这里也是如此,因为“a”=“wwww”的键值对保存在div节点上。});});/script现在知道数据([key],[value])和jquery.data (element,[key],[value])。如果还是半懂,回去再读一遍,耐心理解。其实表面上是很不一样的。但本质上还是有联系的。现在理解了原理就可以放心使用了。Jquery.data(元素、[键]、[值])只将数据绑定到参数元素节点。数据([键],[值]),如$('div ')。data('a ',' aaaa '),将数据绑定到与div节点匹配的每个元素。此外,本文还使用了jquery-1.7.2.js的源代码。下载地址:http://demo.jb51.net/jslib/jquery/jquery-1.7.2.min.js.

版权声明:介绍jQuery对象数据缓存的原理和jQuery.data方法的区别是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。