• jQuery 源码解析(七) jQuery对象和DOM对象的互相转换


    jQuery对象是一个类数组对象,它保存的是对应的DOM的引用,我们可以直接用[]获取某个索引内的DOM节点,也可以用get方法获取某个索引内的DOM节点,还可以用toArray()方法把jQuery对象一次性转换成一个数组,例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
    </head>
    <body>
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <script>
            var jObject = $('p');
            console.log(jObject[0].innerHTML)            //输出:1
            console.log(jObject[1].innerHTML)            //输出:2
            console.log(jObject.get(2).innerHTML)        //输出:3
            console.log(jObject.toArray())               //输出:Array(3) [ p, p, p ]     ;每个元素都是一个DOM节点,等于对应的p元素
        </script>
    </body>
    </html>

    将DOM对象转换为jQuery对象就更方便了,直接放到jQuery的构造器内即可,如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
    </head>
    <body>
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <script>
            var p         =     document.getElementsByTagName('p'),        
                result    =    [];                                        
            for(let i = 0;i<p.length;i++)        result.push(i)        //getElementsByTagName获取的是HTMLCollection对象,也是个类数组,我们把它转换为数组格式
    
            console.log( $(p) instanceof $ )                        //输出true        ;表示$(p)是一个jQuery对象
            console.log( $(p).size() )                              //输出:3            ;因为p内有3个DOM元素
    
            console.log( $(p[0]) instanceof $ )                     //输出true        ;表示$(p)是一个jQuery对象
            console.log( $(p[0]).size() )                           //输出:1            ;因为我们只传入一个p[0],只有一个DOM节点
        </script>
    </body>
    </html>

    输出如下:

    原因在代码里注释得挺详细了,嗯,就这样

    源码分析

    writer by:大沙漠 QQ:22969969


     DOM转换成jQuery对象都是在jQuery内部的init()函数内实现的,如下:

    init: function( selector, context, rootjQuery ) {
      /**/
      // Handle $(DOMElement)
      if ( selector.nodeType ) {                  //selector有属性nodeType,则认为selector是DOM元素,例如:$(document.getELementById('d'))
        this.context = this[0] = selector;            //保存该DOM节点的引用
        this.length = 1;                              //设置length属性为1
        return this;                                  //返回this,以支持链式操作
      }
    
      /**/
    
      return jQuery.makeArray( selector, this );  //这里是最后的逻辑,如果selector是数组或伪数组
    },

    makeArray是jQuery内部的一个函数,用于把一个类数组转换成真正的数据,如下:

      makeArray: function( array, results ) {     //将一个类数组对象转换为真正的数组
        var ret = results || [];                    //如果results不存在则修正为空数组,初始化jQuery执行到这里时这里的result等于jQuery对象,也就是上面传进来的this
    
        if ( array != null ) {                      //过滤参数array是null、undefined的情况。
          // The window, strings (and functions) also have 'length'
          // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
          var type = jQuery.type( array );
    
          if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {    //如果array没有属性length 或者 参数array是字符串,或者是函数,或者是正则,或者是Window对象
            push.call( ret, array );                                                                                                        //认为参数array不是数组,也不是类数组对象,调用数组方法push()把该参数插入返回值ret的末尾。
          } else {
            jQuery.merge( ret, array );           //否则认为参数array是数组或类数组对象,调用方法jQuery.merge()把该参数合并到返回值ret中
          }
        }
    
        return ret;
      },

    最后返回该数组,因为我们在第二个参数传递了this,因此makeArray最后会返回this

    对于jQuery对象转换为DOM对象来说,由于jQuery本身就是个类数组对象,因此,我们可以直接用[]获取索引,对于get和toArray方法来说,这些操作定义在jQuery的原型上,也就是jQuery.fn上的,如下:

    jQuery.fn = jQuery.prototype = {  //重写jQueyr.fn
      /**/
      toArray: function() {               //将当前jQuery对象转换为真正的数组,转换后的数组包含了所有元素。
        return slice.call( this, 0 );
      },
      get: function( num ) {              //返回当前jQuery 对象中指定位置的元素或包含了全部元素的数组,
        return num == null ?
    
          // Return a 'clean' array
          this.toArray() :
    
          // Return just the object
          ( num < 0 ? this[ this.length + num ] : this[ num ] );      //直接返回this[num],也就是和我们用[]是一样的,只是封装了一下
      },
      /**/
    }

    我们可以看到对于get来说,就是直接从this[]上获取的,而toArray则调用了数组了slice方法,将类数组转换成真实的数组

  • 相关阅读:
    个人冲刺(八)
    记账本典型用户和使用场景分析
    第九周进度总结
    个人冲刺(七)
    解密微信sqlite数据库
    读取文件内容时,显示的内容明显少于文本长度
    sqlcipher 数据库解密
    Win7系统的虚拟机中安装win7系统
    NSIS笔记
    vector list map set等容器某些函数的使用区别
  • 原文地址:https://www.cnblogs.com/greatdesert/p/11428986.html
Copyright © 2020-2023  润新知