?今天是2017.1.1,新的一天,新的一年,新的一年里繼續夯實基礎知識,在工作中多些項目,多思考,多總結,前端是不斷更新,在更新的過程中也是發現樂趣和挑戰自我的過程,希望年輕的我和年輕的javascript在2017年中一同成長
?
今天又一次封裝了一個盒jquery使用方法相同的庫,每次寫都有新的想法,我想著也是碼農的樂趣之一吧,
今天代碼只實現了jquery中部分常用選擇器的功能,以后部分會繼續更新其余部分,所有代碼的注釋已經寫到行間的注釋了,這僅僅是我自己的理解,不妥之處希望大家評論到下面,共同學習才是進步的最好方式
/*** Created by Jason on 2016/12/31.*/ //jquery 的構造函數 function Jquery(arg){//用來存選出來的元素this.elemenets=[];switch(typeof arg){case 'function' :domReady(arg);break;case 'string' :this.elements = getEle(arg);break;case 'object' :this.elements.push(arg);break;} } //DOM ready onload 如果參數是函數,則進行domReady操作 function domReady(fn){// FF chromeif(document.addEventListener){//jquery中已經省略false,false解決低版本火狐兼容性問題document.addEventListener('DOMContentLoaded',fn,false);}else{document.attachEvent('onreadystatechange',function(){if(document.readyState=='complete'){fn();}});} }function getByClass(oParent,sClass){//高級瀏覽器支持getElementsByClassName直接使用if(oParent.getElementsByClassName){return oParent.getElementsByClassName(sClass);}else{//不支持需要選中所有標簽的類名來選取var res=[];var aAll=oParent.getElementsByTagName('*');for(var i=0;i<aAll.length;i++){//選中標簽的全部類名是個str='btn on red'=aAll[i].className 使用正則 reg=/\b sClass \b/gvar reg= new RegExp('\\b'+sClass+'\\b','g');if(reg.test(aAll[i].className)){res.push(aAll[i]);}}return res;} }//如果參數是str 進行選擇器的操作 function getByStr(aParent,str){//用來存放選中的元素的數組 這個數組在getEle存在,為了每次執行的時候都需要清空,所以使用局部函數的變量var aChild=[];//aParent開始是[document],再執行完getByStr的時候getEle將aParent指向了getByStr函數的返回值aChild數組以確保循環父級下面的所有匹配元素for(var i=0;i<aParent.length;i++){switch(str.charAt(0)){//id選擇器 eg: #box 使用document.getElementById選取case '#':var obj=document.getElementById(str.substring(1));aChild.push(obj);break;//類選擇器 eg: .box 使用上面封裝的getByClass選取case '.'://由于一個標簽可以有多個類選擇器 所以需要進行循環選取var aRes=getByClass(aParent[i],str.substring(1));for(var j=0;j<aRes.length;j++){aChild.push(aRes[j]);}break;//今天先簡單的編寫選擇器 這里我們假設除了id和類選擇器,就是標簽選擇器default:// 如果是li.red 那么用正則來判斷if(/\w+\.\w+/g.test(str)){//先選擇標簽,在選擇類選擇器 使用類選擇器的時候重復選擇器函數即可var aStr=str.split('.');var aRes=aParent[i].getElementsByTagName(aStr[0]);var reg=new RegExp('\\b'+aStr[1]+'\\b','g');//循環選取標簽,注意外層已經有i的循環for(var j=0;j<aRes.length;j++){if(reg.test(aRes[j].className)){aChild.push(aRes[j]);}}//如果是li:eq(2) 或者 li:first這樣的選擇器 書寫正則是的時候注意()可有可以無為? 有或者沒有為* 至少有一個也就是若干個為+ {2,5}這種則為2-5個}else if(/\w+\:\w+(\(\d+\))?/g.test(str)){//講str進行整理 [li,eq,2] 或者 [li,first]var aStr=str.split(/\:|\(|\)/);//aStr[2]是eq、lt、gt傳入的參數,這里使用n來保存var n=aStr[2];//在父級下獲取所有匹配aStr[0]項的標簽var aRes=aParent[i].getElementsByTagName(aStr[0]);//這時候會循環判斷aStr[1]項是的內容,jquery中經常使用的為eq、lt、gt、even、odd、first、lastswitch(aStr[1]){//如果是eq則把第n項傳入aChild數組即可case 'eq':aChild.push(aRes[n]);break;//如果是lt需要將aRes數組中獲取到的小于n的標簽循環推入aChild中case 'lt':for(var j=0;j<n;j++){aChild.push(aRes[j]);}break;//如果是gt則和lt相反case 'gt':for(var j=n;j<aRes.legth;j++){aChild.push(aRes[j]);}break;//如果是event的話需要隔數添加,注意jquery中的event是從第0開始循環的case 'event':for(var j=0;j<aRes.length;j+=2){aChild.push(aRes[j]);}break;//如果是odd的和event不同的只是從第1項開始循環case 'odd':for(var j=1;j<aRes.length;j+=2){aChild.push(aRes[j]);}break;//如果是first,則將aRes[0]推入aChildcase 'first':aChild.push(aRes[0]);break;case 'last':aChild.push(aRes[aRes.length-1]);break;}//屬性選擇器 eg:input[type=button] 同樣適用正則來判斷}else if(/\w+\[\w+\=\w+\]/g.test(str)){//將屬性選擇器切成數組 [input,type,button]var aStr=str.split(/\[|\=|\]/g);var aRes=aParent[i].getElementsByTagName(aStr[0]);//在選中標簽中選出有aRes[1]的屬性for(var j=0;j<aRes.length;j++){//把屬性值為aRes[2]的標簽推入aChild中if(aRes[j].getAttribute(aStr[1])==aStr[2]){aChild.push(aRes[j]);}}//標簽選擇器 div、span}else{var aRes=aParent[i].getElementsByTagName(str);for(var j=0;j<aRes.length;j++){aChild.push(aRes[j]);}}break;}}return aChild; }function getEle(str){//如果是字符串的話先要去除收尾空格 eg:" on replace index play auto "var arr = str.replace(/^\s+|\s+$/g,'').split(/\s+/g);var aChild = [];var aParent = [document];for(var i = 0;i<arr.length;i++){aChild = getByStr(aParent,arr[i]);aParent = aChild}return aChild; }//實現jquery $符號的寫法 function $(arg){return new Jquery(arg); }
轉載請注明。。