基於jq原理,實現原生js對基本選擇器的封裝
首先,此代碼是參照jq源碼的思想,用原生js實現對基本選擇器的封裝,下面先貼出代碼:

1 (function(window) { 2 var jQ = function(selector) { 3 return new jQ.prototype.init(selector); 4 } 5 jQ.prototype = { 6 length:0, 7 init:function (selector){ 8 var _document = window.document, 9 selector = selector.trim() 10 classInt = 0; 11 if(typeof selector != 'string' || !selector) { 12 return this; 13 } 14 var mark = selector.charAt(0); 15 if(mark == '#') { 16 this[0] = _document.getElementById(selector.substring(1)); 17 classInt++; 18 } else { 19 var tags = ''; 20 if(selector.charAt(0) == '.' || selector.charAt(0) == '*') { 21 tags = _document.getElementsByTagName('*'); 22 } else { 23 tags = _document.getElementsByTagName(selector); 24 } 25 for(var i=0; i<tags.length;i++) { 26 if(selector.charAt(0) == '.' && tags[i].getAttribute('class') == selector.substring(1)) { 27 this[classInt] = tags[i] 28 classInt++; 29 } else if( selector.charAt(0) != '.' ){ 30 this[classInt] = tags[i] 31 classInt++; 32 } 33 } 34 } 35 this.length = classInt; 36 return this; 37 }, 38 css:function(_style,col) { 39 for(var i=0;i<this.length;i++) { 40 this[i].style[_style] = col; 41 } 42 } 43 } 44 jQ.prototype.init.prototype = jQ.prototype; 45 return window.$ = jQ; 46 })(window) 47 48 $('#aaa').css('background','red'); //調用,是不是很眼熟
此代碼只支持對 id、class、標簽及“*”選擇器,下面就大概講講其思路:
1.括號運算傳入‘window’(jq還傳入'undefined',我這里沒用的就沒寫,主要是解決低版本瀏覽器修改值)我覺得2點考慮:a是jq很龐大,傳入后能准確定位到'window'這一層,b是方便壓縮
2.一般我們實例化的都是jq這個方法,但是在這里它實例化的是jq原型下的init()方法:
,相當於這里2步就變成了一步完成;
3.然后再把jq原型prototype賦值給init的原型上,在init上就可以調用原型上的方法了。
4.就是把jq這方法賦值給$,然后掛載在window下就暴露給外部可以調用了。
下面我對以上代碼大概講下起原理:
此圖反映的是在jq下和用原生js下各自實現li背景顏色變紅的方式,但是 jq是基於面向對象的設計,換言之,就是$(li)和css()這2個方法里面的aLi都是局部變量,2個方法之間沒法直接的調用;
jq的處理方式:在構造函數中,只有’this‘是公共的,所有它把aLi存放在"this"上面,存放格式是:{0:li,1:li,length:2},由於存了length這個自變量,所有雖然是json格式,也可以用for循環來處理。
所以,在我的代碼里面我也借鑒了jq的這種做法,存放在“this”下,然后,在css()方法中:
就可以利用for循環來處理了
封裝選擇器是在init()方法中:
在init()方法中,最后返回this,它上面的屬性外部就可以調用了;在jq中,判斷id,class...都是通過正則去做的,我這里比較簡單粗暴。
以上就是我對jq選擇器這一部分的理解,然后自己基於面向對象的方式封裝的基本選擇器不對之處,請留言,我改正。