JQuery源碼解析-添加JQuery的一些方法和屬性

來源:互聯網
上載者:User

標籤:

在這部分中,主要是添加一些JQ的方法和屬性,如:

JQuery:2.0.3 JQ版本

constructor:JQuery 重新指向JQ建構函式

init(): 初始化和參數管理的方法。

selector:儲存選擇字串

length:this對象的長度

toArray():轉換數組的方法

未完

代碼解析:

這部分的代碼都包含在

jQuery.fn = jQuery.prototype = {};

首先是對JQ版本的賦值和重指向:

jquery: core_version,constructor: jQuery,

這裡需要住的是重指向,看如下代碼:

 function Obj() {        }        Obj.prototype.age = 10;        var o1 = new Obj();        console.log(o1.constructor); //function Obj(){}        function ObjNew() {        }        ObjNew.prototype = {            age:10        }        var o1New = new ObjNew();        console.log(o1New.constructor); //function Object(){}

運行代碼可以看到,第二種通過字面量賦值的方式,對象上的constructor會丟失。因為這種方式是將原型上的對象進行覆蓋操作,而不是添加。所以在JQ源碼中需要重新指定一下。

INIT方法:

init方法是JQ最先執行的方法,通過這段代碼進行調用:

jQuery = function( selector, context ) {        // The jQuery object is actually just the init constructor ‘enhanced‘        return new jQuery.fn.init( selector, context, rootjQuery );    },

init方法會接收三個參數,分別是:

selector:$()括弧中的第一個參數。如:"#id" ".class" "<li>" document  function()等

context:執行的上下文

rootJquery:JQ的根對象。

然後定義變數,並檢查selector是否為空白也就是對 $(""),$(null),$(undefind),$(false) 進判斷。

var match, elem;// HANDLE: $(""), $(null), $(undefined), $(false)if ( !selector ) {      return this;}

通過校正之後,接著是判斷selector的類型:

if ( typeof selector === "string" ) {    //實現代碼} else if ( selector.nodeType ) {    //實現代碼} else if ( jQuery.isFunction( selector ) ) {    //實現代碼}

依次對字串、節點、函數進行判斷,並分別進行了單獨的處理

先對字串中的代碼進行解析:

if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {                // Assume that strings that start and end with <> are HTML and skip the regex check                match = [ null, selector, null ];            } else {                match = rquickExpr.exec( selector );            }

首先對字串進行判斷,如果傳入的selector是"<li>"或"<li>1</li><li>2</li>"這種形式想要建立節點的,則 match=[null,"<li>",null]或則 match=[null,"<li>1</li><li>2</li>",null]

否則進行正則匹配,例如:$("#id"),$(".class"),$("div") 這種形式的。

match=null;//$(".class") $("div") $("#div div.class")

match=["#id",null,"id"]  //$("#id")

match=["<li>hello","<li>",null] //$("<li>hello")

這裡先對JQ的內部執行有一個說明,例如:$("li").css("background","red") 這段代碼,對頁面上的所有li的背景顏色賦值。那麼這句代碼的兩部分分別做了什麼處理呢。

首先 $("li") 其實是選擇了頁面上所有的li,並返回了一個this對象存放這些li的節點,

然後通過這個對象在對.css方法進行調用,在css方法內部的實作類別似於:

for(var i=0;i<this.length;i++){  this[i].style.background="red";}

瞭解完這個過程在看下面的代碼:

if ( match && (match[1] || !context) ) {
  }

這個判斷首先判斷math不為null,並且match[1]有值,那麼這就代表建立標籤的語句滿足條件,或者context為空白,context為空白代表是選擇id,因為id沒有上下文,所以滿足這個條件的有:

$("<li>"),$("#id")

接下來在條件裡進一步判斷:

if ( match && (match[1] || !context) ) {    // HANDLE: $(html) -> $(array)    if ( match[1] ) { //判斷是建立標籤還是id                  } else {      //id執行這          }    

在這個條件裡又將建立標籤和尋找id區分。

先看建立標籤的源碼:

    context = context instanceof jQuery ? context[0] : context;                    // scripts is true for back-compat                    jQuery.merge( this, jQuery.parseHTML(                        match[1],                        context && context.nodeType ? context.ownerDocument || context : document,                        true                    ) );

這段代碼中,先將context賦值,在建立標籤時,有是可能需要第二參數,這個第二個參數也就是執行內容,例如:$("<li>",document) 一般很少這樣使用,但是當頁面中有iframe時,想在iframe中建立,那麼第二參數設定為iframe後,就在iframe中建立了。

context instanceof jQuery ? context[0] : context 這句目的就是將context賦值為原生的節點,當我傳遞參數時,可能會:

1、$("<li>",document)

2、$("<li>",$(document))

這兩種形式,同過這判斷是否用第二種形式傳入,如果是,則將原生的document對象賦值。

然後用到兩個方法:jQuery.merge和jQuery.parseHTML方法。

先說一下jQuery.parseHTML方法,代碼如下:

  var str = "<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li>";        var arr = jQuery.parseHTML(str, document, true);        console.log(arr);

執行結果為,

可以看到這個方法是將字串轉換為數組的形式。需要特別注意的最後一個參數,預設為false,為false代表不可以插入script代碼,為true則代表可以。

再看下jQuery.merge方法

這個方法常用的功能就是將兩個數組合并,如:

     var arry1 = ["a", "b"];        var arry2 = ["c", "d"];        var arry3 = jQuery.merge(arry1, arry2);        console.log(arry3); //["a", "b", "c", "d"]

但這裡的this對象是個json對象,通過他也可以進行合并。並返回jq想要的json格式。如:

  var arry1 = {            0: "a",            1: "b",            length:2        };        var arry2 = ["c", "d"];        var arry3 = jQuery.merge(arry1, arry2);        console.log(arry3); 

結果如下:

接下來處理特殊的形式,也是很少使用的一種建立標籤的方式,代碼如下:

if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {                        for ( match in context ) {                            // Properties of context are called as methods if possible                            if ( jQuery.isFunction( this[ match ] ) ) {                                this[ match ]( context[ match ] );                            // ...and otherwise set as attributes                            } else {                                this.attr( match, context[ match ] );                            }                        }                    }

這種匹配的是:$("<li>",{title:"hello",html:"aaaaaaa"}) 後面有個json對象當參數的方式。

如果是這種方式的話,那麼會迴圈這個json對象,先判斷json裡的屬性是否是jq內建的方法,如果是,則直接調用方法,否則,進去else,用jq的attr方法為這個標籤加一個屬性。

到這裡建立標籤的方式就介紹完了。下面介紹一下傳入id形式的代碼。

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 ) {                        // Inject the element directly into the jQuery object                        this.length = 1;                        this[0] = elem;                    }                    this.context = document;                    this.selector = selector;                    return this;

代碼很簡單,但需要注意一下判斷,這是為了最黑莓瀏覽器的相容,因為在黑莓4.6版本的瀏覽器中,當刪除節點之後,還可以用js代碼尋找到這個節點,

所以需要進行一下父節點的判斷,因為任何節點都會有父節點。

接下來也是返回一個JQ需要的特殊json格式。賦值長度為1,第一個對象是當前尋找到的對象。然後把上下文賦值document,賦值selector。

到這裡已經把建立標籤和id尋找的源碼分析完了,其他複雜尋找的代碼會進入下面的代碼:

    } 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 );            }

這段代碼的判斷就是要保證$("ul",document).find("li")  $("ul",$(document)).find("li")  這兩種形式,都會執行:jQuery(document).find();這個方法。

到這就把當參數是字串傳入時,要執行的代碼解析完了,下面分析傳入節點或者方法時要執行的代碼。

 

JQuery源碼解析-添加JQuery的一些方法和屬性

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.