基于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选择器这一部分的理解,然后自己基于面向对象的方式封装的基本选择器不对之处,请留言,我改正。