jquery源碼解析:jQuery原型方法init的詳解

來源:互聯網
上載者:User

標籤:style   io   ar   color   使用   sp   for   strong   on   

先來瞭解幾個jQuery方法:

<li></li>

<li></li>

<li></li>

$("li")  ->  this  ->  jQuery對象  ->    {  0 : "li", 1 : "li", 2 : "li", length : 3  }

$("<li>aaa")  的效果跟   $("<li>")的效果是一樣的。

然後來看一下init方法,也就是建立jQuery對象調用的方法:

jQuery.fn = jQuery.prototype = {

  jquery: core_version,        //jQuery的版本

  constructor:jQuery,          //修正constructor的指向,不寫這個的話,constructor會指向Object,因此你重寫了JQuery的prototype。

   //建立一個建構函式時,會自動在建構函式的prototype對象中新添constructor屬性(指向建構函式)。但是為了防止原型對象的覆蓋,比如:Person.prototype = {};這時裡面的constructor指向會出問題,需要修正,Person.prototype = { constructor: Person}

  init:function(selector,context,rootjQuery){

    var match,elem;

    if(!selector){             //處理這種情況:$(""), $(null), $(undefined), $(false)

      return this;

    }

    if ( typeof selector === "string" ) {
      if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
        // $("<li>")  ->   match = [ null, "<li>", null ];

        // $("<li>1</li><li>2</li>")  ->   match = [ null, "<li>1</li><li>2</li>", null ];
        match = [ null, selector, null ];

      } else {

        //    此正則rquickExpr匹配後,會出現以下幾種情況:

        //  1. match = null;           $(".box"), $("div"), $("#div1 div.box")

        //  2. match = ["#div1",null,"div1"];    $("#div1")

        //  3. match = ["<li>aaa","<li>",null];  $("<li>aaa")     

        match = rquickExpr.exec( selector );
      }

      // $("#div1")通過id匹配元素,是在document中執行,不會傳入context,所以context為空白,因此進入if語句
      if ( match && (match[1] || !context) ) {


        if ( match[1] ) {   // $("<li>"), $("<li>aaa"),$("<li>1</li><li>2</li>")

          //context就是document,因為建立元素只能在document中執行。但是頁面裡面有iframe時,iframe中的document與頁面的document不同,所以$("<li>",document)有第二個參數。一般用不上。
          context = context instanceof jQuery ? context[0] : context;

          //$("<li>",$(document)),得到原生的document。         

          jQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,
true
          ) );

          //parseHTML方法:第一個參數傳入標籤字串"<li>",第二個參數傳入執行內容document,第三個參數true代表可以建立script標籤"<script><\/script>"(script前面的反斜線需要轉義,其他標籤不需要),false代表不能。傳回值是一個數組:$("<li>") ->   ["li"],  $("<li>1</li><li>2</li>") ->["li","li"]

          //merge方法是把數群組轉換成jQuery對象:["li"] ->  {0:"li",length:1} ;["li","li"]   ->  {0:"li",1:"li",length:2}

          rsingleTag匹配單標籤的,$("<li>"),$("<li></li>")
          if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {

            //$("<li>",{title:"hi",html:"abcd"})  針對這種情況的,context 為json對象。
            for ( match in context ) {
              //如果屬性是jQuery方法,就執行方法
              if ( jQuery.isFunction( this[ match ] ) ) {
                this[ match ]( context[ match ] );

              
              } else {

                //如果不是方法,就設定屬性。
                this.attr( match, context[ match ] );
              }
            }
          }

          return this;

         
        }

        else {
          elem = document.getElementById( match[2] );

          // Blackberry 4.6:elem存在,但是頁面上沒有,所以添加了elem.parentNode,如果都滿足,則elem一定存在頁面上。
          
          if ( elem && elem.parentNode ) {
            this.length = 1;
            this[0] = elem;
          }

          this.context = document;
          this.selector = selector;    //"#div"
          return this;
        }

     
      }

      else if ( !context || context.jquery ) {
          return ( context || rootjQuery ).find( selector );  //rootjQuery  = $(document)

          // 處理這種$(expr, context),context是否是jQuery對象(context.jquery存在就是jQuery對象),會轉換成$(context).find(expr)

          //或者$(expr),會轉換成$(document).find(expr)
      }

      else {   //如果context存在,但是不是jQuery對象,就執行
          return this.constructor( context ).find( selector );   //建立jQuery對象,並調用find方法
      }       

    }

    else if ( selector.nodeType ) {       //如果是dom節點,比如:$(document)  
          this.context = this[0] = selector;
          this.length = 1;
          return this;

    }

    else if ( jQuery.isFunction( selector ) ) {     //文檔載入有兩種方式:$(function(){});$(document).ready(function(){});
          return rootjQuery.ready( selector );
    }

    if ( selector.selector !== undefined ) {      //$($("#div1")),當傳入jQuery對象時
        this.selector = selector.selector;
        this.context = selector.context;
    }

    return jQuery.makeArray( selector, this );     //傳入數組和json對象時,比如:$([]),$({})

    //makeArray把selector(類數組)轉換成數組(外部使用),當傳入第二個參數時(內部使用),就會轉換成jQuery對象的形式。

  },

  length:0,    //匹配到的元素的長度,預設為0.

  ......

};

 

加油!

jquery源碼解析:jQuery原型方法init的詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.