html5android課程集合jquery剖析4.jQuery原型定義包含核心方法_第1頁
html5android課程集合jquery剖析4.jQuery原型定義包含核心方法_第2頁
html5android課程集合jquery剖析4.jQuery原型定義包含核心方法_第3頁
html5android課程集合jquery剖析4.jQuery原型定義包含核心方法_第4頁
html5android課程集合jquery剖析4.jQuery原型定義包含核心方法_第5頁
免費預覽已結(jié)束,剩余100頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

varjQuery=//jQuery原型定義(包含 jQuery.fn=jQtotype={...};jQtotype=jQuery.extend=jQuery.fn.extend=//后面依次有多個對jQuery//后面依次有多個對jQueryjQuery.support=(function() jQuery.event={...};//Event類似于Java的POJO類.傳 jQuery.Event=function(src,props)jQuery.find= //將定義的jQuerywindow.jQuery=window.$=29. extend一一.jQuery和$)。由于閉包屬性,雖然函數(shù)自執(zhí)行結(jié)束了,但自執(zhí)行函數(shù)里面定義的局部函數(shù) 看懂這段我們先看看jQuery的使用。jQuery采用鏈式調(diào)用(如:$("#id").data("xxx")),這樣就知道$("#id")返回的是一個jQuery對象。但是調(diào)用的方式是函數(shù)調(diào)用。這個問題就成為了:varjQuery=function(selector,context)//ThejQueryobjectisactuallyjusttheinitconstructorreturnnewjQuery.fn.init(selector,context,rootjQuery4.jQtotype=??的constructor定義為jQuery,上面的問題不是迎刃而解么?varvarjQuery=function(selector,context)returnnewjQuery(selector,3.varjQuery=function(selector,context)returnnewA(selector,varA=if(this.init)9.9.10.A.prototype=的方法。但是還是感覺A定義的有些多余,是不是?new成對象)initinit函數(shù)會自動執(zhí)行,也不用這里可能還有個fnfnjQtotype的,jQuery支持自己擴展屬性,這個對外提供了一個接口,jQuery.fn.extend()來對對象增加方相對于文字,圖形化更加直觀,對上面的來去畫了個圖,更好的理解:newjQuery.fn.init(selectorcontextrootjQuery)對象方式,我還有另一Js代碼varvarjQuery=function(selector,context)//如果以$("#id")方式調(diào)用this就不是jQuery.這樣返回jQueryif(!(thisinstanceofjQuery))returnnewjQuery(selector, if(this.init) 9.//jQtotype=三.框架里最看extend函jQuery.extend({...})jQuery.fn.extend({...})代碼。這里先extendjava<Javascrip繼承文章不同,也都jQuery中有2中調(diào)用形式:varns=ns.Ajax=那為什么這里不是對象,而是函數(shù)做一個命名空間呢?其實在js中一切都是對象!包括函數(shù)也是對象(說Java一切都是對象,我覺得其實這句話形容js更加貼切)。第二種調(diào)用我成為對象調(diào)用,因為.data()new個對象才能調(diào)我們看代碼jQuery.extend=jQuery.fn.extend=function(){...};這個是連等,也就是2個指向同一個函數(shù),怎么會實現(xiàn)不同的功能呢?這就是this的功能了。jQuery.extend調(diào)用的時候,this是指向jQuery對象的(jQuery是函數(shù),也是對象!),所以這里擴展在jQuery上。而jQuery.fn.extend調(diào)用的時候,this指向fn對象,而上圖 看到,jQuery.fn和是原型方法,也就是對象方法了。所以jQuery的api中提供了以上2中擴展函數(shù)。一種是類級別的插件開發(fā),即給jQuery添加新的全局函數(shù),相當于給jQuery類本身添加方法。jQuery的全局函數(shù)就是屬于jQuery命名空間的函數(shù),另一種是對象級別的插件開發(fā),即給jQuery對象添加方法。下面就兩種函數(shù)的開發(fā)做詳細的說明。法。典型的例子就是$.AJAX()jQuery名空間中。關于類級jQuery.foo=function()jQuery.foo=function()alert('Thisisatest.ThisisonlyajQuery.foojQuery.foo=function()alert('Thisisatest.ThisisonlyajQuery.bar=function(param)alert('Thisfunctiontakesaparameter,whichis"'+param+ 1.4foo:function()alert('Thisisatest.Thisisonlyabar:function(param)alert('Thisfunctiontakesaparameter,whichis"'+param1.3jQuery.myPluginjQuery.myPlugin=foo:function()alert(alert('Thisisatest.Thisisonlyabar:function(param)alert('Thisfunctiontakesaparameter,whichis"'+param+}形式1:。//Ourpluginimplementationcodegoes5.6.7. 如:(function($)$.fn.pluginName=function()//Ourpluginimplementationcodegoes4.5.為出來的,都可以在"hilight"函數(shù)中 $.fn.hilight=function()//Ourpluginimplementationcodegoes3. //plugin$.fn.hilight=function(options)//Extendourdefaultoptionswiththose//Notethatthefirstargtoextendisanemptyobject//plugin$.fn.hilight=function(options)vardefaults={foreground:'red',background:'yellow' //Extendourdefaultoptionswiththoseprovided.varopts=$.extend(defaults,options);//Ourpluginimplementationcodegoes10.foreground:14.//thisistokeepfromoverridingour"defaults"varopts=$.extend({},$.fn.hilight.defaults,//Ourpluginimplementationcodegoes//plugindefaults-addedasapropertyonourplugin$.fn.hilight.defaults=foreground:background:13. //這個只需要調(diào)用一次,且不一定要在ready$.fn.hilight.defaults.foreground=////d:'green'2.4適當 ////plugin$.fn.hilight=function(options)//teandreformateachmatchedreturnthis.each(function()var$this=//varmarkup=////callourformatmarkup= 12.//defineourformat$.fn.hilight.format=function(txt)return'<strong>'+txt+ format函數(shù)進而讓他能被重方Cycle插件對使用者"transitions"對象,使他們添加自己變換定義。插件中定義就像這$.fn.cycle.transitions=//2.5性。一個通理是,如果你不能肯定是否特定的函數(shù),那么你也許不需要那樣做。那么我們怎么定義的函數(shù)而不攪亂命名空間也不實現(xiàn)呢?這就是閉包的功能。為了演示,會添加另外一個“debug”函數(shù)到我們的插件中。這個debug函數(shù)將為輸firebug控制臺。為了創(chuàng)建一個閉包,包裝整個插件定義在(function($)(function($)//plugin$.fn.hilight=function(options)// //privatefunctionforfunctiondebug($obj)if(window.console&&window.console.log('hilightselectioncount:'+//Metadata插件是否被安裝如果它被安裝了,它能擴展我們的options對象通過抽取元數(shù)據(jù)這行作為最后一個參數(shù)添加到jQuery.foo()$.fn.hilight=function(options)////buildmainoptionsbeforeelement varopts=$.extend({},$.fn.hilight.defaults,returnthis.each(function(){var$this=$(this);//buildelementspecificvaro=$.meta?$.extend({},opts,$this.data()):<!--markup--<divclass="hilight{background:'red',foreground:'white'Haveanice<divclass="hilight{foreground:'orange'Haveanice<divclass="hilight{background:'green'Haveanice現(xiàn)在我們能高亮哪些div僅使用一 2.7創(chuàng)建(function($)插件的定$.fn.hilight=function(options){//buildmainoptionsbeforeelement varopts=$.extend({},$.fn.hilight.defaults,// teandreformateachmatchedreturnthis.each(function()$this=//buildelementspecificvaro=$.meta?$.extend({},opts,$this.data())://updateelementcolor: varmarkup=//callourformatmarkup= //私有函數(shù):debuggingfunctiondebug($obj)if(window.console&&window.console.log('hilightselectioncount:'+ //定 $.fn.hilight.format=function(txt)return'<strong>'+txt+ //插件的$.fn.hilight.defaults={foreground:'red',background:'yellow' 38.閉包結(jié)jQuery為開發(fā)插件提拱了兩個方法,分別是:jQuery.fn.extend(object);給jQuery對象添加方法。jQuery.extend(objectjQuery類本身.為類添加新的方法。jQuery.fn=jQtotype=init:function(selector,context)javascript沒有明確的類的概念,但是用類來理解它,會更方便。jQuery便是一個封裝得非常好的類,比如我們用語句$("#btn1")會生成一個jQuery類的實例。}$("#input1").alertWhileClick(頁面上為:<inputid="input1"$("#input1"jQueryalertWhileClick39.便為便為jQueryadd的“靜態(tài)方法”jQuery的地方,使用這個方法了,$.add(3,4);//return7*jQuery源碼分析-extend函*jQuery版本** *函數(shù)介*jQuery.extend與jQuery.fn.extend*jQuery.extend是jQuery的屬性函數(shù)(靜態(tài)方法*jQuery.fn.extend是jQuery函數(shù)所構(gòu)造對象的屬性函數(shù)(對象方法** *使用說*1.對象合并*對象合并不區(qū)分調(diào)用者,jQuery.extend與jQuery.fn.extend完全一*也就是說對jQuery對象本身及jQuery所構(gòu)造的對象沒有影*如:$.extend({ObjectObject$.extend({Boolean},{Object**2.為jQuery對象本身增加方法*形式為*jQuery.{Fnction**3.原型繼承*原型繼承方式可以為jQuery所構(gòu)造的對象增加方*形式為*這種方式實際上是將{Object}追加到jQtotype,實現(xiàn)原型繼***//jQuery.fn=//jQuery.fn.extend=jQuery.extend=jQuery.fn.extendfunction(){vartarget=arguments[0]||{}, i=length=arguments.length, deep=false, //只有當?shù)谝粋€實參為true時,即需要進行深度拷貝時,執(zhí)行以下分if(typeoftarget==="boolean")//deeptrue,deep=target;target=arguments[1]||{}; 參數(shù),因此i指向的位置為第二個參i= //當目標對象不是一個Object且不是一個Function時(函數(shù)也是對象,因此使if(typeoftarget!=="object"&&{target= {{{{//$.extend({Object$.extend({Booleanif(length===//targetthis;這句代碼是整個extend//$.extend()方式中表示jQuery//$.fn.extend()方式中表示jQuery函數(shù)所構(gòu)造的對象(即jQuery類的實例)target=this;自減}for(;i<length;if((options=arguments[i])!=//遍歷當前參數(shù)對象的屬性,屬性名記錄到for(nameinsrc=copy=if(target===copy)}if(deep&©&&inObject(copy)||Array(copy))) //如果src類型為對象或數(shù)組,則clone記錄 //否則colne記錄與copy類型一致的空值(空數(shù)組或空對象varclone=src&& inObject(src)||isArray(src))?src:jQuery.isArray(copy)?[]:{144.147.//對copytarget[name]=jQuery.extend(deep,clone,}elseif(copy!==//直接將target[name]=}}}}return*jQuery框架本身對extend*典型示例為*//使用extend對jQuery對象本身進行擴展,//該對象中的屬性將被追加到jQueryajax://3個參數(shù)jQuery.ajaxSettings(即jQuery默認ajax配置 //s就得到了最終的ajaxvars=jQuery.extend(true,{},jQuery.ajaxSettings,}173.。1.幾個"全局變量window=_jQuery=_$=jQuery=window.jQuery=window.$=function(selector,context)returnnewjQuery.fn.init(selector,//AsimplewaytocheckforHTMLstringsorIDstringsquickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,//IsitasimpleisSimple=window還是那個windowundefinedundefined,只是這樣讓js(function()3.:function(deep{window.$=if(deepwindow.jQuery=return。然后調(diào)用jqprototype.js jqjQuery$)jQueryquickExprhtmltag或id字符串(isSimple也是一個與此同時表達式,selectorcss選擇器__jQuery=_$=jQuery$,jqueryjQuery$_jQueryjQuery.fn.init1.jQtotype=jQuery=window.jQuery=window.$=function(selector,context)returnnewjQuery.fn.init(selector,3.vara=$('#id');//a=newjQuery('#id');jQuery.fn=jQtotype=init:function(selector,context)size:function()return jQuery.extendjQuery.extend=jQuery.fn.extend=function()vartarget=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(typeoftarget==="boolean")deep=target=arguments[1]||i=if(typeoftarget!=="object"&&!jQuery.isFunction(target))target={};if(length==i{target=objectobject為targetobject的成員擴展如果僅有一個objectthis(jQuery或jQuery.fn)target,object的成員將添加到target中varb$.extenda); options$.extend'name''editor'value'100'options)myfuncfunction為jquery添加10.13. myplugin:function為jquery17.for(;i<length;i++if((options=arguments[i])!=nullfor(varnameinoptions)varsrc=target[name],copy=options[nameif(target===copyif(deep&©&&typeofcopy==="object"&&etarget[name]=jQuery.extend(src||(copy.length!=null?[]:{},copyelseif(copy!==undefined//argsisforinternalusageeach:function(object,callback,args)varname,i=0,length=if(args)if(length===undefined)for(nameinobjectif(callback.apply(object[name],args)===false}for(;i<length;if(callback.apply(object[i++],args)===false//Aspecial,fast,caseforthemostcommonuseof12.}else。2.2each(object,}elseif(length===undefined)for(nameinobject target[name]=copy;19.returnif(callback.call(object[name],name,object[name])===alse}for(varvalue=i<length&&callback.call(value,i,value)!==value=object[++i]//Seetest/unit/core.jsfordetailsconcerning//Sinceversion1.3,DOMmethodsandfunctionslike//aren'tsupported.TheyreturnfalseonIEisFunction:function(obj)returntoString.call(obj)==="[objectisArray:function(obj)returntoString.call(obj)==="[object10.1.vara=['a','b','c','d','e'];$.each(a,function()alert(this);//this即每次迭代的5.$.each(a,function(index,value)//9.$.each(a,function()if(this=='c')return // 15.最后,最后,eachobject2.3isFunction(obj),isArray(obj),注isXMLDocAPIgrep:function(elems,callback,inv)varret=for(vari=0,length=elems.length;i<length;i++if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return//checkifanelementisina(orisan)XMLisXMLDoc:function(elem){returnelem.nodeType===9&& Element.nodeName!=="HTML" &&jQuery.isXMLDoc( 16.2.4trim:function(text)return(text|| ce(/^\s+|\s+$/g,""grep(array,callback,insert),map(array,strip:function()return ce(/^\s+/, ce(/\s+$/,3.vara=[2,3,6,1,8,$.grep(a,function(v) 只要3returnv>=$.grep(a,function(v)returnv>=false這樣相當于map:function(elems,callback)varret=for(vari=0,length=elems.length;i<length;i++{varvalue=callback(elems[i],iif(value!=nullret[ret.length]=returnret.concat.apply([],ret11.a=[1,2,3,b=$.map(a,function(v)return[v,2*//b=[1,2,2,4,3,6,4,下面是下面是returnconcat(ret[0ret[1vara=[].concat(1,2,3,[4,5]);//a=[1,2,3,4,makeArray:makeArray:function(array)varret=if(array!=nullvari=//Thewindow,strings(andfunctions)alsohaveif(i==null||typeofarray==="string"||jQuery.isFunction(array)||array.setInterval)ret[0]=while(iret[--i]=return15.inArray:function(elem,array)for(vari=0,length=array.length;i<length;i++//Use===becauseonIE,windowif(array[i]===elemreturnreturn---2.6makeArray(obj),inArray(value,merge:function(first,second)//WehavetoloopthiswaybecauseIE&Operaoverwritethe//expandoofvari=0,elem,pos=//Also,weneedtomakesurethatthecorrectelementsarebeing17.//(IEreturnscommentnodesina'*'if(!jQuery.support.getAll)while((elem=second[i++])!=nullif(elem.nodeType!=8)first[pos++]=}while((elem=second[i++])!=null)first[pos++]=elem;return但是我不知道jQuery.support.getAll是哪里來的?1.jQuery(element);//anhtmldom1.//HandlejQuery.fn=jQtotype=init:function(selector,context){selector=selector|| 1.jQtotype=jQuery=window.jQuery=window.$=function(selector,context)returnnewjQuery.fn.init(selector,context3.if(typeofselector==="string")//ArewedealingwithHTMLstringoranvarmatch=quickExpr.exec(selector//Verifyamatch,andthatnocontextwasspecifiedforif(match&&(match[1]||!context))//HANDLE:$(html)->if(match[1]selector=jQuery.clean([match[1]],contextquickExprhtmlstringid(1篇)$('<divid="new-div"varelem$(elementhtmldom元素,jQuery操作它。elem[0];//returnhtmldom2.jQuery(html,[context]),jQuery(elements,if(selector.nodeType){this[0]=selector;this.length=1;this.context=selector;returnthis;7.//HANDLE:elsevarelem ementById(match[3]//HandlethecasewhereIEandOperareturn//bynameinsteadofif(elem&&elem.id!=match[3]returnjQuery().find(selector//Otherwise,weinjecttheelementdirectlyintothejQueryvarret=jQuery(elem||[]ret.context;ret.selector=return15.setArray馬上就會分析到(因為下面用到3.returnthis.setArray(jQuery.isArray(selector)selectorselectorhtmldom元素的數(shù)組。以下三個看喜歡選用$(function(){...})IEhack$('#id')vardomvarelm=elm.context=elm.selector='#id'';;$('#id') ement4.}}elseif(jQuery.isFunction(selector)return ).ready(selectorif(typeofselector==="string")varmatch=quickExpr.exec(selectorif(match&&(match[1]||!context))}returnjQuery(context).find(selectorif(selector.selector&&selector.context)this.selector=this.context=returnthis.setArray(jQuery.isArray(selector)selector6.vara= --jQueryAPICorejQueryObjectAccessors1.。2.setArray:setArray:function(elems)this.length=0;Atotype.push.apply(this,elems);returnthis;5.each:each:function(callback,args)returnjQuery.each(this,callback,args3.size:function()return3.eq:eq:function(i)returnthis.slice(i,+i+1+i,+i,0+i,常用于轉(zhuǎn)成整形(+new<divclass="mydiv"<divclass="mydiv"<diviclass="mydiv"<divclass="mydiv"<divclass="mydiv"5.get(),3.3.get:get:function(num)returnnum===undefinedAtotype.slice.call(this)this[num5.6.index:index:function(elem)returnelem&&elem.jquery?elem[0]:,this5.cache實際的數(shù)據(jù)存放在這data:function(elem,name,data)indexjQueryDatafunctionfunctionreturn+new3.gojQuery.data將一個對象和一個htmldom關聯(lián)。讓我們可以管理節(jié)點相關數(shù)據(jù)。見API文檔:http 1.varexpando="jQuery"+now(),uuid=0,windowData=elemelemwindowwindow進行特殊處理(在IE==varidelem[expando節(jié)點上其實僅僅存一個uuid,expandoif(!ididelemexpandouuid;節(jié)點沒有uuidif(name&&!jQuery.cache[id]jQuery.cache[id]={};<spanstyle="white-space:an>if(data!==undefinedjQuery.cache[idnamedata;<spanstyle="white-space:pre;"></span>//存數(shù)據(jù)returnnamejQuery.cache[id][name]:<spanstyle="white-space: id;<spanstyle="white-space:pre;"/span> removeData:function(elem,name)elemelemwindowspanstyle="white-space:pre;"/span>windowDatavaridjQuery.data(elm)varvalue=jQuery.data(elm,varvalue=jQuery.data(elm,name,再看jQuery.removeData(elem,name);datavarid=elem[expandoifnamespanstyle="white-space </span>//僅僅移除if(jQuery.cache[id])deletejQuery.cache[id][namejQuery.cache[idname=for(nameinjQuery.cache[id]if(!namejQuery.removeData(elemelse{<spanstyle="white-space: <spanstyle="white-space:dtrydeleteelem[expando}<spanstyle="white-spacepre;">ttribute進行移除if(elem.removeAttribute</span>//先刪除dom節(jié)點上的</span>IE下需要使用30.<spanstyle="white-space: deletejQuery.cache[iddata:function(key,valuevarparts=parts[1]=parts[1]?"."+parts[1]:if(value===undefined)vardata=this.triggerHandler("getData"+parts[1]+"!",if(data===undefined&&this.lengthdata=jQuery.data(this[0],keyreturndata===undefined&&parts[1]this.data(parts[0])}returnthis.trigger("setData"+parts[1]+"!",[parts[0],valujQuery.data(this,key,valuetriggerHandler('getData.def!',['abc'])--->jQuery.data(elem,'abc.def')-->jQuery.data(elem,'abc') o o o1.<inputid="tags"type="text"vartagsvartags'Javascript''jQuery''Web前端Js代碼1.1.<spanstyle="white-space:on(e,name)1.vartags=if(name=='tags')return}).bind('setData',function(e,name,value)if(name=='tags')queue:function(elem,type,data)if(elemtype=(type||"fx")+varq=jQuery.data(elem,typeif(!q||jQuery.isArray(data)q=jQuery.data(elem,type,jQuery.makeArray(data)elseif(dataq.push(datareturnjQuery.queue,ChainofResponsibilityActiveObjects模式,讓我們可以把操作串dequeue:function(elem,typevarqueue=jQuery.queue(elem,type),fn=queue.shift();if(!type||type==="fx"fn=if(fn!==undefined)10.queue:function(type,if(typeoftype!=="string"{data=type=if(data===undefinedreturnjQuery.queue(this[0],typereturn(PS(PSreturnqif里面更好type'fx'Effectsdataarray,queue用makeArray,下面看degueue:jQuery.queuejQuery.dequeuejQuery對象對它們進行了包裝,讓我們varqueue=jQuery.queue(this,type,dataif(type=="fx"&&queue.length==1$('#id').queue(function()...); 相當于$('#id').queue('fx',function()...); 作到fx$('#id').queue();$('#id').queue('fxdequeue:returnthis.each(function(){jQuery.dequeue(this,type); 5. 傳統(tǒng)的構(gòu)造對象方法.jquery提供了一種截然不同的方法.它選擇創(chuàng)造一個首先所有的首先所有的jquery變量給外界盡量避開變 裹起來,=function(function(window,window和undefined都是為了減少變量查找所經(jīng)過的scope.當window通過傳遞給閉包內(nèi)部之后,在閉包 可以把它當成一個局部變量,顯然比原先在windowscope下查找的時候要快一些.,undefined,而是一個普普通通的變量名..varjQuery= varjQuery=function(selector,context return(window.jQuery=window.$=jq1,這個jQueryreturn(window.jQuerywindow.$jQuery)的時候會window.jQuery=window.$=returnwindow.而jq2供jquery內(nèi)部執(zhí)行的時候調(diào)用window.jQuery=window.$=returnwindow.現(xiàn)在來看看jquery對象是怎么被創(chuàng)建出來的jquery作為一個獨立特行的庫,它產(chǎn)生它寧愿選擇這種方式,比如要產(chǎn)生一個構(gòu)造函數(shù)Man的對象returnnewvarpe=10.alertfunction(selector,context){}varjQuery=function(selector,context)returnnewjQuery.fn.init(selector,context .jQuery.fn=jQtotype={},newjQuery來生成jquery對象也可以.跟直接用jQuery()沒區(qū)別this對象好比說,有只母雞被你強迫下一個蛋,它會先看窩里有沒有別人的蛋,如果沒有,才會自己,.添加方法了JQueryapi里的方法大部分都是通過jQtotype擴展上去的,除此之外.我們還要給jquery對象加上索引.給集合添加length屬性,讓他們更像一個數(shù)組里的元素.,我們可以把jQtotype.init想象成一個火腿腸加工器.只要你放了正確的原料進去,它就可以把原料變成火腿腸生產(chǎn)出來.如果你不放錯了原料.它也會幫你變成火腿腸.不過只有塑料包裝,里面沒有火腿.當然這個加工器里面的構(gòu)造是很復雜的,它需要判斷材料種類,數(shù)量等等domjQuery的構(gòu)造方 生成一組jquery對象的集合.具體關于init方法的分析,還是留在選擇二二jQuery對 jqueryjquery構(gòu)造完對象之后,會提供一些方 get:function(num)returnnum==null//如果參數(shù)為null或者undefiend注意是this.toArray()://如果不傳參數(shù)集合內(nèi)的元素全部轉(zhuǎn)化為一個數(shù)(num<0?this.slice(num)[0]:this[num](1this.toArray函數(shù)toArray:function()returnslice.call(this,0很簡單,就是讓當前jquery對象冒充Array的對象,調(diào)用Atotype.slice進行截斷.返.其實如果查看v8之類開源引擎的源碼就知道(ecma里掙扎一番).要調(diào)用Array原型鏈上的方法.通常這個對象滿足2個條件就可以了.1,本身可以存取屬性.. array.js可以找到這些方法functionfunctionArrayPush()varn=對象/length如果為null或者undefined,會在ToUint32013.varm=for(vari=0;i<m;i++)this[i+n]= this.length=n+return可以看到push操作 就 .string類型的不可以,因為不能在string上存取屬性function對象雖然可以存取屬性,也有l(wèi)ength屬性.length屬性比較特殊,表示形參的個數(shù),是一個只讀屬性,this.lengthn+m這一句不起作用,所以function對象也不行.同理window對象也不行.,varavara=a[0]=a[1]=alert a沒有l(wèi)ength屬性0值所以結(jié)果為1如果在pusha.length再進行push操作后a.length3了沒有什么特別需要解釋的,直接看代碼index:function(elem)if(!elem||typeofelem==="string")//如果沒有參數(shù)或者參數(shù)是選擇器returnjQuery.inArray(elem?jQuery(elem):this.parent().children()//如果沒有參數(shù)查找元素本身在它的兄弟節(jié)點之間的位置this.parent().child8.returnelem.jquery?elem[0]:elem,this//如果是jquery對象取得它的原始節(jié)點13.顧名思義jQuery.inArray就是判斷數(shù)組里有沒有某個元素.當然這里的數(shù)組也包括偽數(shù)組.這個方法雖然實現(xiàn)起來很簡單,inArrayjquery的卻有頗多爭議.很多人認為它應該返回true或者false,而不是索引的位置. if(Atotype.indexOf){jQuery.inArray=function(elem,arrayif(Atotype.indexOf){jQuery.inArray=function(elem,array){returnindexOf.call(array,elem 5.Atotype.indexOfjQuery.inArray,直接用Atotype.indexOf.call(array,elem);.inArray:function(elem,array)if(array.indexOf)//確認indexOf方法存在.或防止indexOf方法被改寫returnarray.indexOf(elem forfor(vari=0,length=array.length;i<length;i++)//否則遍歷數(shù)組返回正確的索引if(array[i]===elem)return return-1;//如果數(shù)組里沒有這個元素返回- 在實際應用中,我們經(jīng)常需要往節(jié)點中緩存一些數(shù)據(jù).dom元素緊密相關.dom節(jié)點也是對象,所以我們可以直接擴展dom節(jié)點的屬性.不過肆意污染dom節(jié)點是不良少年的行為.我們需要一種低耦合的方式讓dom和緩存數(shù)據(jù)然后往需要進行緩存的dom節(jié)點上擴展一個值為jQuery.expando的屬性,這里是”jquery”(newDate).getTime().id的值就作為cachekey用來關聯(lián)dom節(jié)點和數(shù)據(jù). cache=dom1[jQuery.expando]:{key1:value1,key2:5.dom2[jQuery.expando]{key3:value3,key4:9.10.jQuery.expando的值等于”jquery”+當前時間,元素本身具有這種屬性而起 , <divvarDatafunction(){varcache={};varexpando="zengtan"++newvaruuid=varsetData=function(elem,value){varid=if(!id){ id=++uuid;elem[expando]=if cache[id]=cache[id][key]=vargetData=function(elem,varidelem[expando];//取得cache里跟dom節(jié)點關聯(lián)的returngetData:35.vardiv Data.setData(div,"name",varvalue=Data.getData(div,alert首首 noData:"embed"://BanallobjectsexceptforFlash(whichhandleexpandos)"object":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000","applet": acceptData方法中,1.42版本相比,這里多了對什么flash的object的特殊處理.data:function(elem,name,data)if(!jQuery.acceptData(elem)) elem=elem==windowwindowData//elem是window的情況如果不單獨處理的話等于增加了一個全局變量windowData也是一個{}varisNode=//判斷是不是dom節(jié)點,由于非dom節(jié)點的緩存在繼承和內(nèi) 本已經(jīng)把dom節(jié)點和其他對象分開處理了id=isNode?elem[jQuery.expando]:null,cache=jQuery.cache,thisCache;//因為存數(shù)據(jù)的時候會給elemjQuery.expando設置一個全局唯一標志量是否為undefined,就知道已經(jīng)有沒有往這個元素上緩存過數(shù)據(jù) if(isNode&&!id&&typeofname==="string"&&data===undefined){//如果是dom節(jié)點對象并且現(xiàn)在是get方式(typeofnamestring"&&dataundefinedget方式又沒有緩存(!id表示沒有緩存 if(!isNode)cache=//如果是非dom節(jié)點對象取緩存里的屬性就直接取元素本身屬性}elseif(!id)elem[jQuery.expando]=id=//第一次進行緩存分配一個全局唯一標志}if(typeofname==="object")//如果keyif(isNode)cache[id]=jQuery.extend(cache[id], 到原來的緩存上,比"v2":"v3": "," 1.42版本用的cacheidjQuery.extend(truename這樣會清}elsejQuery.extend(cache,name }}elseif(isNode&&!cache[id]) //cacheid中沒有東西表示這個元素第一次進行緩存或者緩存已被清空,設置cache[id]為一個新的map.cache[id]= thisCache=isNode?cache[id]:if(data!==undefined) set操作也可以防止一些意外的情況下緩存被清空比如data未定義的情況下,緩存操作是無效的.vara=var$(a).data("c", $(a).data("cbb為undefined.這句是無效的要移除緩存可以用removeData方法.thisCache[name]= //cacheidnamedata把data設置進cache緩存對象中前面分配的自增id當做key來關聯(lián)returntypeofname==="string"?thisCache[name]://如果key是string類型返回key對應的緩存68.,上面的靜態(tài)方法之外.的處理,event部分再講當然我們用jquery緩存系統(tǒng)的時候,上面的靜態(tài)方法之外.的處理,event部分再講,.removeData:function(elem,name)if(!jQuery.acceptData(elem))elem=elem==windowwindowDatavarisNode=id=isNode?elem[jQuery.expando]://id是該元素在cache上面的key,如果不是節(jié)點就返回元素本身.cache=jQuery.cache,thisCache=isNode?cache[id]:if(name)if(thisCache)deletethisCache[nameif(isNode&&jQuery.isEmptyObject(thisCache)西,,注意現(xiàn)在走的是下面else分支.jQuery.removeData(elem}elseif(isNode&&jQuery.support.deleteExpando)//如果支持delete,見特性檢測部分.deleteelem[jQuery.expando];}elseif(elem.removeAttribute)elem.removeAttribute(jQuery.expando}elseif(isNode{deletecache[id//如果是dom節(jié)點,全局緩存里刪除以這個id為key的對象}elsefor(varninelem)//如果是其它對象刪除對象的所有屬性deleteelem[n.}}}} queuedequeue主要為動畫服務jquery的動畫里,因為javascript的單線程異步機制,如果要管理一批動畫的執(zhí)行順序,而不是讓它們一起在屏幕上飛舞.一般我們是一個一個的把下個動畫寫在上個動畫的回調(diào)函數(shù)中意味著如果要讓十個動畫按次序執(zhí)行.至少要寫9個回調(diào)函數(shù).現(xiàn)在有了隊列機制可以把動畫都放到隊列中依次執(zhí)行.究竟怎樣把動畫填充進隊列.用的是queue方法.,<styleeft:110px;}left:<divid="div1">我是一個<divid="div2">我是另一個用queue可以這樣做<script //fn=== 27.28.首先我們需要一個載體,來保存這個隊列,這里選擇 .其實選什么節(jié)點都一樣queue的參數(shù)是一個數(shù)組.里面的函數(shù)就是隊列依次執(zhí)行的函數(shù).前面講到queue 意味著這些代碼寫完后,div1已經(jīng)開始漸漸隱藏了.隱藏完畢后,如果要讓后面的動畫繼續(xù)執(zhí)行,還要用$( 當然這個操作是放在第一個動畫的回調(diào)函數(shù)里,以此類推,第二個.dequeue()要放在第二個 ).dequeue().因為這句代碼太長.注意隊列函數(shù)里有一,在看源碼之前先自己來想想這個功能應該怎么實現(xiàn)首先我們需要一個數(shù)組,里面存放那些動畫.2個方法setget.可以存取動畫可能我們還需要一個變量來模擬線程鎖,保證隊列里的函數(shù)不會同時被執(zhí)行,看源碼,先是prototype方法jQtotype.queuejQtotype.queue=function(type,data)if(typeoftype!=="string"){data=type;type=//type,默認為表示jquery動畫的fx,如果不為"fx"即為自己的自定義動畫 if(data===undefined)returnjQuery.queue(this[0],type//get隊列不論集合中是單個或者多個元素 returnthis.each(function(i,elem)varqueue=jQuery.queue(this,type,dataif(type==="fx"&&queue[0]!=="inprogress")數(shù)隊列就不受控制了jQuery.dequeue(this,type//如果隊列沒有被鎖住即此時沒有在執(zhí)行dequeue移出隊列里第一個函數(shù)并執(zhí)行它//畢竟queue的主要任務是添加隊列執(zhí)行函數(shù)的操作上只能當二等公民 看看jQuery.queue這個靜態(tài)方法jQuery.queue=function(elem,type,data)if(!elem) type=(type||"fx")+"queue";varq=jQuery.data(elem,type);if(!data)//如果當data為空只是查詢queue那么返回隊列或者returnq||if(!q||jQuery.isArray(data))q=jQuery.data(elem,type,jQuery.makeArray(data)//如果q為null,說明緩存上沒有隊列此時哪怕隊列里只有一個函數(shù)也把它轉(zhuǎn)成數(shù)組保//q不為null說明緩存上已經(jīng)存在隊列但是如果現(xiàn)在被添加的函數(shù)是一個數(shù)組的話,以現(xiàn)在的數(shù)組來代替原來的隊列,即把原來的隊列清空了.}elseq.push(datareturn}48.再看dequeuedequeue的原型方法什么也沒做直接把參數(shù)交給jQuery.dequeue來處理63.71.dequeue:function(elem,type)type=type||varqueue=jQuery.queue(elem,type),fn=//取得隊列和隊列里的第一個元素這里直接給shift掉了先斬后奏if(fn==="inprogress")fn=,if(fn)if(type==="fx"{//函數(shù)執(zhí)行前在queue數(shù)組的最前面添加一個進程鎖fn.call(elem,function()如果是dequeue操作,去掉鎖,執(zhí)行隊列里的函數(shù),同時給隊列加上鎖.如果是queue操作要看鎖的狀態(tài)如果被鎖上了,就只執(zhí)行隊列的添加操作.其實dequeue和queue都可以執(zhí)行隊列里的第一個函數(shù).queue操作添加完隊列之后會調(diào)用dequeue方法去執(zhí)行函數(shù).但是用dequeue執(zhí)行函數(shù)的時候,這時候如果又用queue觸發(fā)dequeue的話,很可能同時2個函數(shù)在執(zhí)行.隊列就失去一大半意義了(還是可以保證順序,2個動畫會同時執(zhí),,.clearQueue:function(type)returnthis.queue(type||"fx",[] 原理上面已經(jīng)提到過了,if(!q||jQuery.isArray(data))q=jQuery.data(elem,type,jQuery.makeArray(data)3.五多庫共存可能很多人都被多庫共存時的$變量問題困擾過.比如你先引入了prototype庫,然后又引入了jquery.因為jquery的$會覆蓋prototype的$.現(xiàn)在想調(diào)用現(xiàn)在想調(diào)用prototype的$怎么辦呢, Jquery代碼里最開始就有一句_$=window.$,在加載的時候就用_$來 :function(deep){window.$=_$;//window.$歸還給原來的庫要回歸jquery再用window.$jQuery就可以了if(deep)window.jQuery=//如果deep為truejQuery這個變量也可以歸還不過一般不需要也不推薦這么做 return jQuery元素集來提供新的方法,或者把一個對象的屬性拷貝到另外一個對象上實例繼承(這個有點特殊主要用于繼承內(nèi)置對象 原型繼承在性能方面好一些,可以共享原型鏈.但查找屬性慢,因為可能要遍歷N條原型鏈才找到某個屬性.而且原型鏈太多,會使得結(jié)構(gòu)越加.并且會丟失對象的constructor屬性(對象的constructor總是指向原型鏈最上層的構(gòu)造器).,jquery里采用的是屬性拷貝.其實用哪種繼承是個見仁見智的問題.也有其它一些庫就是用前面也可以注意到,jquery只在構(gòu)造方法或者原型鏈上定義了少量的 方法.其它功能塊都是通過extend函數(shù)拷貝上去.按需定制.好比開發(fā)商交給我們房子的時候只安裝了水電暖氣等基本設施.電視機洗衣機顯然是自己,for(variinObj1[i]=3. 深度繼承是指如果被繼承對象和繼承對象都有同名屬性a,而且這個屬性的值分別是一個對bc.會把bc的屬性都合并到一個新的對象里,作為值返回給合并后的對象.說的有點復雜,看個例子jQuery.extend(jQuery.extend({name:“John”,location:{city:“Boston”}{last:“Resig”,location:{state:“MA”} name:“John”,last:location:{city:“Boston”,state:“MA” ,jQtotypejQtotype上,jQuery對象.用這個辦法可以很方便的編寫插件,.不同的方式進行copy操作.jQuery.extend=jQuery.fn.extend=function()vartarget=arguments[0]||jQuery.extend=jQuery.fn.extend=function()vartarget=arguments[0]||{},i=1,length=arguments.length,deep=false,options,name,src,copy,copyIsArray;,,if(typeoftarget==="boolean") deep=//重新設置target=arguments[1]||//修正target,讓它指向第二個參i=//修正循環(huán)開始的位置,copy的時候跳過deep和target,指向第一個copy對象if(typeoftarget!=="object"&&!jQuery.isFunction(target))//target確保target是一個可以迭代屬性的對象從這句代碼看出target=if(length===i{target=當只有一個參數(shù)是對象的情況(可能前面還有一個true或把屬性賦值給jquery或者jquery.fn.幫jquery實現(xiàn)繼承}for(;i<length;i++)if((options=arguments[i])!=null)fornameinoptions//copysrc=target[name]; //記錄target的屬性值copyoptionsname];//copy進去的值if(target===copy){//防止死循環(huán)???}if(deep&©&&(Array=jQuery.isArray(copy))))inObject(copy)||//如果是深度繼承并且copy是對象字面量或者數(shù)組//copyIsArrayjQuery.isArray(copy)返回的是//如果inObject(copy)和jQuery.isArray(copy)是false,那整個if語句里的判斷條件都返回//也就不會執(zhí)行下面了的深度繼承了.比起1.42版本很多地方功能沒變,代碼還是明顯清晰了很多.if(copyIsArray){ copyIsArrayfalsecopyIsArrayclone=src&&jQuery.isArray(src)?src://防止深度copy的時候target為undefined.此時target型要跟copy對象保持一致.}elseclone=src&&inObject(src)?c:}target[name]=jQuery.extend(deep,clone,copy//深度繼承遞歸調(diào)用extend}elseif(copy!==undefined){target[name]=copy;屬性但是不要帶入undefined值}}}}65.return//返回合并后的對象.第一個objjQuery2.0.3源碼分析core整體架整體架上是jquery-master,加入了AMD規(guī)范了整整體 2varvaraQuery=function(selector,context)}aQtotype=}vara=new這是常規(guī)的使用方法,顯而易見jQuery不是這樣玩的 jQuerynew運行符將jQuery 要實現(xiàn)這樣,那么jQuery$()應該是返回類的實例才對varvaraQuery=function(selector,{returnnew}aQtotype{}通過newaQuery(),雖然返回的是一個實例,但是也能看出很明顯的問題,死在javascript中實例thisvarvaraQuery=function(selector,{return}aQtotype{){return}}當執(zhí)行aQuery很明顯aQuery()返回的是aQuery類的實例,那么在init中的this向的aQuery類的實例問題來了initthisaQueryinit那么內(nèi)部的this要如何處理?varvaraQuery=function(selector,{return}aQtotype{init:{this.age=18returnthis;name:function(){},age:20}aQuery().age這樣的情況下就出錯了,因為this只是指向aQueryjQuery=jQuery=function(selector,context)//ThejQueryobjectisactuallyjusttheinitconstructorreturnnewjQuery.fn.init(selector,context,rootjQuery很明顯通過實例init函數(shù),每次都構(gòu)建新的initthis,避免交varaQuery=functionva

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論