zoukankan      html  css  js  c++  java
  • 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 })()

      结果如下:很好的模拟了

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

  • 相关阅读:
    [GXYCTF2019]BabyUpload
    [GYCTF2020]Blacklist
    [极客大挑战 2019]HardSQL
    PHP实现MVC框架路由功能模式
    色环电阻的阻值识别
    python的内存回收机制
    配置Openfiler做ISCS实验
    windows server 2008r2 在vmware里自动关机
    VMware Workstation网络修改vlan id值
    linux的服务自动启动的配置
  • 原文地址:https://www.cnblogs.com/yanggeng/p/10823074.html
Copyright © 2011-2022 走看看