zoukankan      html  css  js  c++  java
  • jQuery 源码分析(二) 入口模块

    jQuery返回的对象本质上是一个JavaScript对象,而入口模块则可以保存对应的节点的引用,然后供其它模块操作

    我们创建jQuery对象时可以给jQuery传递各种不同的选择器,如下:

      false        ;返回一个空jQuery对象

      DOM节点      ;返回包含该DOM元素引用的jQuery对象。

      body        ;字符串'body',返回包含body元素引用的jQuery对象

      单独标签      ;调用document.createElement创建标签对应的DOM元素

      较复杂的html代码  ;调用jQuery.buildFragment创建元素

      函数        ;是$(document).ready(function)的简写,等到DOM加载完毕后再执行,后面有几篇专门介绍

    例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
    </head>
    <body>
        <p id="p">123</p>
        <script>
            console.log( $(false) )
            console.log( $(p) )
            console.log( $('body') )
            console.log( $('<p>123</p>') )
            $(function(){console.log('Dom loaded')}) 
        </script>
    </body>
    </html>

    输出如下:

    输出的五条信息分别对应上面的五个输出,第一条为空jQuery对象,第二条为包含p元素的jQuery对象,第三条为包含body节点引用的jQuery对象,第四条为jQuery创建的未挂载到dom的jQuery对象,第五条就直接输出信息的,对应着例子的$(function(){})对象

     源码分析


     writer by:大沙漠 QQ:22969969

     入口模块就是上一篇文章分析的jQuery内部的jQuery.fn.init函数,该函数会通过参数的不同来做不同的实现,如下:

      init: function( selector, context, rootjQuery ) {           //负责解析参数selector和context的类型,并执行相应的逻辑
        var match, elem, ret, doc;
    
        // Handle $(""), $(null), or $(undefined)
        if ( !selector ) {                                                        //selector是"",null,undefined和false的等可以转换为false的情况下,对应上面的第一个jQuery实例
          return this;
        }
    
        // Handle $(DOMElement)
        if ( selector.nodeType ) {                                                //selector有属性nodeType,则认为selector是DOM元素,例如:$(document.getELementById('d'))对应上面的第二个jQuery实例
          this.context = this[0] = selector;
          this.length = 1;
          return this;
        }
    
        // The body element only exists once, optimize finding it
        if ( selector === "body" && !context && document.body ) {               //如果参数selector是字符串'body',且context为空,如:$('body'),对应上面的第三个jQuery实例
          this.context = document;
          this[0] = document.body;
          this.selector = selector;
          this.length = 1;
          return this;
        }
    
        // Handle HTML strings
        if ( typeof selector === "string" ) {                                   //参数selector是字符串形式
          // Are we dealing with HTML string or an ID?
          if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {       //如果参数selector以"<"开头、以">"结尾,且长度大于等于3
            // Assume that strings that start and end with <> are HTML and skip the regex check   
            match = [ null, selector, null ];                                                                                     //则假设这个字符串是HTML片段,跳过正则quickExpr的检查。注意这里仅仅是假设,并不一定表示它是真正合法的HTML代码
    
          } else {
            match = quickExpr.exec( selector );                                                                               //否则用quickExpr来检测参数selector是否为稍微复杂一点的代码,
          }
    
          // Verify a match, and that no context was specified for #id
          if ( match && (match[1] || !context) ) {
    
            // HANDLE: $(html) -> $(array)
            if ( match[1] ) {
              context = context instanceof jQuery ? context[0] : context;
              doc = ( context ? context.ownerDocument || context : document );
    
              // If a single string is passed in and it's a single tag
              // just do a createElement and skip the rest
              ret = rsingleTag.exec( selector );
    
              if ( ret ) {                                                      //如果参数selector是单独标签比如$('<p></p>');
                if ( jQuery.isPlainObject( context ) ) {
                  selector = [ document.createElement( ret[1] ) ];
                  jQuery.fn.attr.call( selector, context, true );
    
                } else {
                  selector = [ doc.createElement( ret[1] ) ];
                }
    
              } else {
                ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
                selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
              }
    
              return jQuery.merge( this, selector );
    
            // HANDLE: $("#id")
            } else {                                                            //参数selector是"#id"格式,如:$('#p1')
              elem = document.getElementById( match[2] );
    
              // Check parentNode to catch when Blackberry 4.6 returns
              // nodes that are no longer in the document #6963
              if ( elem && elem.parentNode ) {
                // Handle the case where IE and Opera return items
                // by name instead of ID
                if ( elem.id !== match[2] ) {
                  return rootjQuery.find( selector );
                }
    
                // Otherwise, we inject the element directly into the jQuery object
                this.length = 1;
                this[0] = elem;
              }
    
              this.context = document;
              this.selector = selector;
              return this;
            }
    
          // HANDLE: $(expr, $(...))
          } else if ( !context || context.jquery ) {
            return ( context || rootjQuery ).find( selector );
    
          // HANDLE: $(expr, context)
          // (which is just equivalent to: $(context).find(expr)
          } else {
            return this.constructor( context ).find( selector );
          }
    
        // HANDLE: $(function)
        // Shortcut for document ready
        } else if ( jQuery.isFunction( selector ) ) {                           //如果参数selector是函数,则认为是绑定ready事件,从这里可以看出$(function) 是$(document).ready(function)的简写,这里对应上面的第五个jQuery实例
          return rootjQuery.ready( selector );
        }
    
        if ( selector.selector !== undefined ) {
          this.selector = selector.selector;
          this.context = selector.context;
        }
    
        return jQuery.makeArray( selector, this );
      },

    这样jQuery实例就获取到了对应的DOM节点的引用,之后就可以用底层模块或功能模块进行操作了。

  • 相关阅读:
    windows消息定义
    17种正则表达式
    DirectX程序例子
    C#调用WINDOWS API 要点
    提取网页中的超级链接
    基于消息驱动的C#Windows程序
    C#使用事件
    C#启动进程的方法
    C#注册表操作方法
    HighLight.net 2.0 版本源码
  • 原文地址:https://www.cnblogs.com/greatdesert/p/11399137.html
Copyright © 2011-2022 走看看