jQuery 第二章 实例方法 DOM操作选择元素相关方法

进一步选择元素相关方法:

   .get()

  .eq()

  .find()

  .filter()

  .not()

  .is()

  .has()

  .add()集中操作  .end()回退操作

  .get()

  $(".class").get()   可以填 $()选择器选出来的dom 索引,  0  1  2  3   -1  -2 ,   不填  取全部dom, 但是

取出来的dom 不再是jquery的对象,而是原生dom, 用get()取出来的 dom  都为原生dom;

  

  现在会用了,但是咱们不能单单只会用,还要知道其原理,以下模仿其功能,写一个 .get() 方法。

  把上一篇写的 jQuery 函数全部抽出来, 建立一个单独文件为我们自己的 myJquery.js   ,

自己慢慢学,写成一个我们自己的jquery 库

   

 1 (function(){ 
 2     function jQuery(selector){
 3        return new jQuery.prototype.init(selector);
 4     }
 5     jQuery.prototype.init = function(selector){
 6     
 7         if( selector.indexOf('.') != -1 ){ 
 8             var dom = document.getElementsByClassName( selector.slice(1) );
 9         }else if( selector.indexOf('#') != -1 ){
10             var dom = document.getElementById( selector.slice(1) );
11         }else{
12             var dom = document.getElementsByTagName(selector);
13         }
14         this.length = 0;
15         if( dom.length == undefined ){
16             this[0] = dom;  
17             this.length ++; 
18         }else{
19             for( var i = 0; i < dom.length; i++ ){
20                 this[i] = dom[i];
21             }
22             this.length = dom.length;
23         }
24     }
25     jQuery.prototype.css = function(config){
26         for(var i = 0; i < this.length; i++){
27             for(var prop in config){
28                 this[i].style[prop] = config[prop];
29             }
30         }
31         return this;
32     }
33     //以下为我们本章的.get() 方法
34     jQuery.prototype.get = function(num) { 
35         if (num == null) { //判断用户有没有填参数。
36             return [].slice.call(this, 0); //空截,把类数组转成数组,借用Array.prototype.slice方法        
37         } else { 
38             if (num < 0) {//判断用户是否输入 负数。
39                 return this[num + this.length];
40                 //举个例子  [a, b, c]   此数组的长度为3
41                 // 用户输入-1  想要拿最后一位 c,如果你把-1 + 3该数组的长度, 你会发现 刚好等于 最后一位的索引
42             } else { 
43                 return this[num];//如果用户输入 0 1 2 3  直接返回this 中的 dom 即可 
44             }
45         }
46         //以下为简化版本  三目运算符 ↓ 
47         //return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
48 
49     }
50     jQuery.prototype.init.prototype = jQuery.prototype; //$()运行的是init的函数 init的prototype上面没有css方法。
51                                                     //所以 我们把init的prototype指向jQuery.prototype
52     window.$ = window.jQuery = jQuery;
53 })()

  .eq()

  这个方法和.get() 有点像,但是,获取的dom 并不是原生的dom 了,是 jquery对象的dom

除此之外,还有一个不同点,不传参数  .get() 是返回全部原生dom,.eq()是返回空。

  模拟原理,往我们自己的myJquery.js 添加.eq() 方法,你会发现 此方法 和 get方法的原理一样,但是 有点不同,返回的

jquery对象的dom, 我们先在做另外一个功能, 往$() 传 原生dom   会把你传的dom包装成 jquery对象的dom。

  

 1 (function(){ 
 2     function jQuery(selector){
 3        return new jQuery.prototype.init(selector);
 4     }
 5     jQuery.prototype.init = function (selector) {
 6         //加上以下代码
 7         if (selector == null) { //判断 有没有传值,没有传值,直接返回 this  (jquery 对象)
 8             return this;
 9         }
10         //如果还按照以前selector.indexOf('.')的话,传入 dom,dom上面没.indexof方法,会报错,再加上一层判断
11         //typeof selector == 'string'  判断他是字符串 再执行, dom的话,就进不去了 &&运算符,遇到假就返回
12         if(typeof selector == 'string' && selector.indexOf('.') != -1 ){ 
13             var dom = document.getElementsByClassName(selector.slice(1));
14             //      ↓  也要加上哦
15         }else if(typeof selector == 'string' &&  selector.indexOf('#') != -1 ){
16             var dom = document.getElementById( selector.slice(1) );
17         }else if(typeof selector == 'string'){//zheli
18             var dom = document.getElementsByTagName(selector);
19         }
20        
21         this.length = 0;
22          // 主要在这里   加上以下代码 ↓   判断 传进来的值 是否是dom 元素, 是的话,就进去
23         if(selector instanceof Element || dom.length == undefined ){ 
24             this[0] = dom || selector;  // 把selector  直接挂到 this[0] 位上就OK了 
25             this.length ++; 
26         }else{
27             for( var i = 0; i < dom.length; i++ ){
28                 this[i] = dom[i];
29             }
30             this.length = dom.length;
31         }
32     }
33     jQuery.prototype.css = function(config){ 
34         for(var i = 0; i < this.length; i++){
35             for(var prop in config){
36                 this[i].style[prop] = config[prop];
37             }
38         }
39         return this;
40     }
41 
42     jQuery.prototype.get = function(num) { 
43     
44         return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
45     }
46     // 跟 get方法原理差不多,差的就是, 传进去是空的话 返回 null 即可, 
47     jQuery.prototype.eq = function (num) { 
48        var dom =  num == null ? null : (num < 0 ? this[num + this.length] : this[num]);
49         return $(dom); //  如果直接返回 dom  就是返回原生的dom  我们要把他包装一下,变成jquery对象, 此方法
50                         // 在上面已经实现了。
51     }
52     jQuery.prototype.init.prototype = jQuery.prototype; 
53             
54     window.$ = window.jQuery = jQuery;
55 })()

  

  下面几个方法不探究 原理,几乎原理都是用一大堆正则筛选出来的

  .find()

   用法是 在什么之下, 举个例子  $('.wra').find('span1')   这样会选出span1标签, 在.wra 下面 找span1, 

跟$('.wra span1')好像一样,但是 这两个差别还是挺大的。

  $('.wra span1') 其实这样把选择器给 选死了,  jquery的精髓在于链式调用, 你后面的 .  什么方法,全部都在

操作$('.wra span1') 这个, 并不能改变了,如果想再选span2的就得重新选  但是  $('.wra').find('span1')  并不会选死了,

你现在选了span1,你后面假如不想操作span1了,你可以通过 回退操作等方法,返回上一次选择的元素,直接选span2

  

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     <div class="wra">
11         <span class="span1">
12             span1
13         </span>
14         <span class="span2">
15             span2
16         </span>
17     </div>
18 
19 <script src="./jquery/jquery.js"></script>
20  <script>   
21     //第一种选法
22     $('.wra .span1')
23         .css({background:'red'});
24     $('.wra .span2')
25         .css({background:'green'})
26 
27     //使用find()
28     $('.wra')
29             .find('.span1')
30                 .css({background:'red'})
31                     .end()
32                         .find('.span2')
33                             .css({background:'green'})
34             
35                        
36                             
37  </script>
38 </body>
39 </html>

  .filter()

  意思如其名,.filter()方法就是过滤。 可传入  css  selector   jquery   dom 等等,他会按照你传进去的参数,

过滤掉 没有 这个参数的。 还可以传 函数(fn) 传函数,就跟 数组上的 filter方法比较像了 。如图所示,把不是 span2 其他dom给过滤掉了。

  传入函数,函数第一个参数为index 索引,第二个为,ele 元素。处理后需要你返回一个true 或者 false , true表示留下该值

   过滤掉class名不是为 "span2" 的元素

  .not()

  学了filter 之后,自然你就会not了, 为什么,因为not和filter是相反的。

  .is()

  判断是否有交集,我选的东西,里面有没有你;

  

  .has()

  

  像下面这种结构,如果我们想选 li 里面有个p标签的 li 2 用我们现在的选择器,是选不出来的,这个时候,has 就派上用场了
$('ul li').has('p'), 我选是一堆li,但是我加了一个has('p')  意思是,我要选的是li  但是要满足一个条件,li 里面后代元素必须有 p标签的
 1 <ul>
 2         <li>1</li>
 3         <li>
 4             2
 5             <p></p>
 6         </li>
 7         <li>3</li>
 8         <li>4</li>
 9         <li>5</li>
10 </ul>
11 <ul>
12         <li>6</li>
13         <li>7</li>
14         <li>8</li>
15         <li>9</li>
16         <li>10</li>
17 </ul>

  接下来,重头戏来了:

  .add()  和  .end()

.add()  添加元素到匹配的元素集合, 意思就是,$('.wra').add('.dome'), 先选了 .wra元素,然后加上.dome元素,即使没有关系也能加在一起

看个案例吧。像下面这种情况,给两个没有关系的元素加上一样的样式。

   如果有一天,我不想给.wra变成红色了,我想把它绿了,那么这个时候,end() 就派上用场了,他会回退到你上一次选择的地方,不需要你

传参,利用的是  jquery 对象里面 prevObject  属性,每次选择元素,这个属性都会记录你上一次选择的元素是什么,end 就是利用 prevObject 来进行回退的;

  我们来利用end()方法把.wra 给绿了

 

  剖析原理:

  咱们知道,add()方法, 是把 上一次选择,和 自己选择的元素给结合起来,所以,里面肯定有两个 值,第一个是 记录上一次选择的,

第二个是记录 本身自己选择的,还有一个值,是用来接收这两个值 合在一起的,此代码编辑在myJQuery.js文件下

 1 (function(){ 
 2     function jQuery(selector){
 3        return new jQuery.prototype.init(selector);
 4     }
 5     jQuery.prototype.init = function (selector) {
 6         this.length = 0;
 7         if (selector == null) { 
 8             return this;
 9         }
10         if(typeof selector == 'string' && selector.indexOf('.') != -1 ){ 
11             var dom = document.getElementsByClassName(selector.slice(1));
12         }else if(typeof selector == 'string' &&  selector.indexOf('#') != -1 ){
13             var dom = document.getElementById( selector.slice(1) );
14         }else if(typeof selector == 'string'){
15             var dom = document.getElementsByTagName(selector);
16         }
17        
18         
19         if(selector instanceof Element || dom.length == undefined ){ 
20             this[0] = dom || selector;  
21             this.length ++; 
22         }else{
23             for( var i = 0; i < dom.length; i++ ){
24                 this[i] = dom[i];
25             }
26             this.length = dom.length;
27         }
28     }
29     //先看56行
30     jQuery.prototype.pushStack = function (dom) {
31         //这里的this 是$('.wra'),也就是上一次选择的元素, 所以我们把this 加到 你想加的对象上就可以
32         if (dom.constructor != jQuery) {//这里判断 你传进来的值是否为 jquery 对象的dom
33             dom = jQuery(dom); //如果不是,那么就把你变成jquery 对象的 dom。
34         }
35         dom.prevObj = this;//不管是不是 jquery 对象的dom,你最后都是要加上 prevObj属性的。
36         return dom; //返回 加上 prevObj 属性 就是传进来的值。
37     }
38     jQuery.prototype.css = function(config){ 
39         for(var i = 0; i < this.length; i++){
40             for(var prop in config){
41                 this[i].style[prop] = config[prop];
42             }
43         }
44         return this;
45     }
46 
47     jQuery.prototype.get = function(num) { 
48         return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
49     }
50    
51     jQuery.prototype.eq = function (num) { 
52        var dom =  num == null ? null : (num < 0 ? this[num + this.length] : this[num]);
53        return this.pushStack(dom);// 这里做一个小修改,原来我们这里并没有加上 prevObj属性,现在加上
54     }
55 
56     jQuery.prototype.add = function (selector) {//加上add 方法 
57         var baseObj  = this;//谁调用add这个方法,this就是谁,拿到上一个元素
58         var curObj  = jQuery(selector);// 传进来的值,要进行选择,我们之前写过jQuery() 利用它进行选择
59         var newObj = jQuery();//var一个空的jquery对象变量来接收 上面两个元素的集合。
60         
61         for (var i = 0; i < baseObj.length; i++) {//遍历 上一个元素,拿出dom, 赋给newObj
62             newObj[newObj.length++] = baseObj[i];
63         }   //第一次遍历的时候,newObj的length 为0, 每次 赋值后 ++;
64         for (var i = 0; i < curObj.length; i++) { //遍历 传进来的元素,拿出dom, 赋给newObj
65             newObj[newObj.length++] = curObj[i];
66         }
67         //到这里,add的功能就算完成了,但是你会发现,我们写的,没有prevObject 这个属性,接下来添加这个属性
68 
69         //请看30行,我添加了一个为pushStack的方法
70         // this.pushStack(newObj); 此时的this 是谁?谁调用了 我们add方法,this就是谁 我们是$('.wra')
71         return this.pushStack(newObj); //最后把 newObj 返回出去,以供下一次链式调用。
72     }
73 
74     
75     jQuery.prototype.end = function () { //加上end方法
76        //end 这个方法,就是返回上一次选择的元素,那么我们直接把,谁调用它,就把它的prevObj返回就ok
77         return this.prevObj;
78     }
79     jQuery.prototype.init.prototype = jQuery.prototype; 
80             
81     window.$ = window.jQuery = jQuery;
82 })()

  结果如下:很好的模拟了

 觉得有用,点个赞呗, 谢谢你的查看

原文地址:https://www.cnblogs.com/yanggeng/p/10823074.html