Jquery1 4 3原始碼分析(一)

2021-08-31 04:14:47 字數 4086 閱讀 7313

jquery是站在開發者的角度去考慮問題,在使用js的時候,大部分時間都是對dom元素進行操作,比如修改元素的屬性,修改內容,修改css等。但是取dom元素的,如getelementsbytag,有可能會取到一些dom元素的集合,而又正好要這個集合的所有的元素都要進行同樣的操作。如果只有乙個元素,完全可以看作只有乙個元素的集合。

這樣只要對這個集合進行操作,就會對集合的每個元素都進行操作。jquery就是基於這個集合而提供了眾多的實用方法,包含了日常開發所需要的功能。對於這個集合,我們稱為jquery物件。

我們可以通過$(params)或jquery(params)來生成jquery物件。在jquery文件中提供了四種方式:jquery(expression,[context]),jquery(html),jquery(elements),jquery(callback)四種構尋jquery物件的方式。其實jquery的引數可以是任何的元素,如空引數,都能構成jquery物件。

那麼jquery是如何實現的呢?

var jquery = function( selector, context ) ,

現在我們看一下jquery.fn.init函式的實現:

init: function( selector, context )

第一種情況 handle $(domelement)單個dom 元素,忽略上下文

// handle $(domelement)

if ( selector.nodetype )

//如果selector為'body',而且只存在一次,那麼使用優化找到它

// the body element only exists once, optimize finding it

if ( selector === "body" && !context && document.body )

//// handle html strings

if ( typeof selector === "string" ) else

} else

//把建立出來的element放進jquery物件集合中.

return jquery.merge( this, selector );

// handle: $("#id") //處理$("#id")

} else

// 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: $("tag") 處理$('p')

} else if ( !context && !rnonword.test( selector ) ) else if ( !context || context.jquery ) else

// handle: $(function) 處理$(function)

// shortcut for document ready

} else if ( jquery.isfunction( selector ) )

if (selector.selector !== undefined)

// 處理$(elements)

return jquery.makearray( selector, this );

}

上面的可以看出$(xx)或jquery(xx)得到不是真正的jquery函式生成的物件,而是jquery.fn.init函式生成的物件。也是就是jquery的物件繼承的是jquery.fn.init的原型。jquery.fn = jquery.prototype=。我們基本上不用new jquery(xx),而是直接jquery(xx),就是採用了new jquery(xx),先生成jquery函式的物件,把原型中的繼承下來,返回的也是jquery.fn.init函式生成的物件。而jquery函式的物件也拋棄了。可見給jquery.prototype上增加方法的意義不大。同時也可以看出採用new jquery(xx)的效率更低。jquery.fn.init是通過jquery.fn.init.prototype = jquery.fn;來獲得的。在擴充套件jquery的時候,只要把相關的函式extend到jquery.fn就可以了。

jquery.fn.init負責對傳的引數進行分析然後生成jquery物件。它把第乙個引數分成四種情況:

[img]

[img]

從上面的**和上表中,我們也可以看出構建jquery物件就是往jquery物件的集合中新增元素(一般都應該是dom元素)。新增的元素有兩種形式:

一是單個元素,可能通過直接的dom元素的傳參形式,還可以通過#id從dom文件中找元素。

二是集合,如jquery物件,還有陣列,還有通過css selector找到的dom集合等array-like。

上表僅僅是分析傳入的引數的型別,它是怎麼做呢?它實現css1~css3的相容的selector的查尋器的功能。通過jquery().find(selector);來進行分析string並查詢到符合傳入的selector語法的dom文件樹中的元素集合。

它實現了把html的字串轉換成dom元素節點的集合。這個是通過jquery.clean([match[1]], context);來實現的。

它實現domready的jquery物件的統一入口,我們可以通過$(fn)要註冊domready的監聽函式。所有的呼叫jquery實現的功能**都應該在domready之後才執行。$(fn)是所有的應用開發中的功能**的入口。它支援任意多的$(fn)註冊。其是通過return jquery(document)[jquery.fn.ready ? "ready" : "load"](selector);來完成的。

找到元素之後就是構建集合了,就是通過this.setarray(jquery.makearray(selector));來構建jquery物件內部的集合。

在jquery.fn.init函式中,最終的結果是把dom元素放到jquery物件的集合,我們可以傳入單個dom元素或dom元素集合直接把其存到jquery物件的集合。但是如果第乙個引數是string型別的話,如#id就要把dom文件樹去查詢。對於html的片斷就得生成dom元素。我們再進一步,傳入的單個dom元素或dom元素集合引數又是從那裡來的?我們可以通過dom元素的直接或間接的查詢元素的方式。

這一部分首先分析如何從html的片斷就得生成dom元素,然後分析jquery是如何通過直接或間接的方式在在dom樹中找到dom元素,第三就是分析基於css1~css3的css selector。

3.1生成dom元素

init方法中通過ret = jquery.buildfragment( [ match[1] ], [ doc ] );來實現把html片斷轉換成dom元素,這是乙個靜態方法:

jquery.buildfragment = function( args, nodes, scripts ) }}

if ( !fragment )

if ( cacheable )

return ;

};

jquery.clean( args, doc, fragment, scripts );

在上面的**中,我們可以看出對於elems, context的引數的支援是多種形式的,elems可以為(類)陣列的形式,還可以採用物件的形式。陣列中的元素或物件的屬性可以是混合形的,如string,ojbect,甚至(類)陣列的形式。對於數字型別,會轉換在string形,除string形之外的都放入返回的陣列中,當然對於集合的形式,那就會取集合中每個元素。

對於string的形式就轉換成dom元素的形式,之後存到返回的陣列中。這是這個函式的主要任務。對於把html轉換成dom元素,這裡採用innerhtml把html掛到dom文件樹中。這樣就轉換成了dom元素。

有些html標籤片斷是有約束的,比如xx,它必須存在table的tr中,也就是說在要進行html的標籤片斷的修正。這也是上面的**處理的重點。

jQuery原始碼分析(一)

function window,undefined window jquery整體的內部實現都包含在乙個立即執行函式形成的閉包裡,只向外暴露jquery和 兩個變數,避免了全域性變數的汙染。平時我們例項化jquery物件的時候,並不是像例項化普通物件一樣,使用new來例項化,而是直接 這也是jque...

jQuery原始碼分析

工具 版本說明 版本號備註 jquery 2.1.1 sublime 3jquery function selector,context jquery.fn jquery.prototype 快速匹配正則 不加g 不光匹配整體項還會匹配到子項 rquickexpr s w w w init jque...

jQuery原始碼分析

一 jquery如何做到不汙染變數名並暴露出 供使用者使用 jquery將變數和 寫進立即執行函式,通過函式來包裹所有的變數和方法,再在這個立即執行函式上將 jquery方法繫結到window上,就可以讓使用者使用到jq方法了。二 jquery是如何做到 jquery 的?function wind...