本節書摘來自異步社群《擴充 jquery》一書中的第2章,第2.1節,作者:【美】keith wood 譯者: 李強更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
擴充 jquery
本章涵蓋以下内容:
jquery的架構;
建立一個簡單的集合插件。
jquery是一個可以使得與網頁上元素互動更容易的javascript庫。它通常被用于通過直接選擇或者周遊dom來查找元素,然後在這些元素上應用一些功能。開發者可以添加或删除這些元素,或者改變它們的屬性,還可以為它們添加事件處理器用來響應使用者的動作。開發者也可以随着時間推移改變元素的屬性來産生動畫。jquery也提供了ajax讓開發者容易地從伺服器上擷取資料,并且不阻塞目前頁面及其内容。
上一章中提到過jquery不是萬能的,是以它提供了許多擴充點或內建點,進而培育了一個欣欣向榮的第三方插件社群。
本章着眼于jquery的架構,它允許插件與内置的代碼一起工作。然後通過介紹一個簡單的集合插件(可以操作一組元素)來說明可以做些什麼。以後章節将詳細介紹每一個擴充點,以及如何使用它們來提升jquery的能力,并且提出了一套插件開發的指導原則和最佳實踐。
jquery的源代碼由許多檔案組成,這是為了開發階段的需要。在建構階段,它們将會被合并為單個javascript檔案(供産品使用的最小化版本,或者友善調試的完整版本)。每一個源代碼檔案專注于jquery的一個特定功能,其中許多提供了擴充點,可以用來增強内置功能。
一個擴充點是指一個可以用來注冊特定類型(如集合函數或者 ajax 增強)新功能的jquery屬性或者函數,這些新功能被視為和相應的内置功能完全一樣。當架構處理到開發者的插件的引用時,就會調用相應的插件代碼。
圖2.1反映了組成jquery的子產品或檔案,以及它們之間的依賴。

jquery的主要可擴充子產品(圖2.1中的陰影部分)包括:提供了選擇dom元素功能的sizzle庫;包括jquery函數本身的core子產品、處理ajax的ajax子產品、處理事件的event子產品,以及提供動畫功能的effects子產品。
2.1.1 jquery的擴充點
表2.1列出了jquery和jquery ui所提供的擴充點,接下來的幾小節中會介紹它們。回想一下,$是函數jquery的一個别名(除非通過調用noconflict釋放$)。
2.1.2 選擇器
jquery将sizzle選擇引擎作為它自己代碼的一部分。這個獨立的庫用來執行選擇處理,讓開發者在網頁上定位到自己需要的元素。在可能的情況下,它會把操作代理到浏覽器提供的本地函數上以提高性能,其餘部分直接由javascript實作。例如,開發者想在id為preferences的元素中,找到所有跟在input字段(也可能是checkbox的标簽)後的label元素,就可以使用如下代碼:
sizzle允許開發者通過節點名、類名、子節點或屬性值來選擇元素。開發者也可以使用各種僞類選擇器,包括層疊樣式表(css)規範定義的和 sizzle 自己添加的,例如:checked,:even和:not。通過把多個選擇器組合在一個選擇字元串中,開發者可以找到想要的元素。
僞類選擇器
css規範:“僞類基于特征對元素進行分類,而不是基于它們的名字、屬性或者内容;原則上,特征是不可以從文檔樹上推導得到的。”這些選擇器都通過一個冒号(:)後面跟着位置條件(如:nth-child(n))、内容條件(:empty)和否定條件(:not(selector))進行區分。
開發者可以通過擴充$.expr.pseudos(jquery 1.8之前的版本中是$.expr.filters)添加自己的僞類選擇器,并在選擇過程中使用。最後要說的是,一個選擇器隻不過是一個函數,它接收一個元素作為參數,如果這個元素被接受,則傳回true,被拒絕,則傳回false。
通過擴充$.expr.setfilters,開發者可以在目前的一組比對元素中,通過位置進行過濾元素。開發者需要提供一個函數,它傳回比對到的元素集合(jquery 1.8之後版本)或傳回一個布爾标志來辨別是否包含(jquery 1.7及之前版本)。
關于如何為jquery/sizzle添加自定義選擇器和過濾器的詳細内容,請參見第3章。
2.1.3 集合插件
集合插件是最為常用的jquery擴充,被用來操作使用選擇器或者周遊dom得到的一組元素。
這些插件必須擴充$.fn,用一個函數來實作自己的功能。這樣,它們就能被整合到jquery内置的處理流程中。如果讀者看一下源碼,會發現$.fn隻是$prototype的别名。這就意味着,任何加入$.fn的函數對所有jquery集合對象都是可用的,例如使用選擇器或者dom元素調用jquery得到的結果。這樣,這些函數就能在恰當的上下文中在這些集合上調用。
所有集合插件都應該傳回目前元素集合,或者當它提供了某種形式的周遊功能時,也可以傳回一個新集合。這樣,它們就能與其他jquery函數一起鍊式調用——jquery操作的一個核心範式。
第4章将介紹一系列包括最佳實踐的原則。第5章則介紹一個實作了這些最佳實作的插件開發架構。
2.1.4 工具函數
可以通過直接擴充$把那些不能操作元素集合的javascript函數(例如内置的trim和parsexml)添加到jquery中。雖然不是必須把它們包括到jquery中來(它們也可以被定義為獨立的javascript函數),但這樣它們可以充分利用jquery的其他功能,并且保證使用風格的統一。另外,把它們加進來也減輕了全局命名空間的混亂,降低了命名沖突的可能性,同時也保證功能相關的函數能放在一起。
工具函數沒有固定的參數清單,但是它們可以接收需要的任何參數。
第6章将介紹如何為jquery添加新的工具函數。
2.1.5 jquery ui小部件
jquery ui是官方提供的一組建構在基本jquery庫之上的ui元件、行為和特效。它提供了一個實作最佳實踐原則的小部件開發架構。
通過調用jquery ui的$.widget函數可以建立小部件。這個函數的第一個參數是新的小部件的名字(包括命名空間來防止名字沖突);第二個參數是可選的,用來指定繼承的基“類”;第三個參數是一組自定義函數和覆寫,用來增強基本的功能。小部件架構會負責把小部件應用在選擇好的元素上,并設定、擷取和儲存控制小部件外觀和行為的選項,還有當小部件不再需要時的清理工作。函數$.widget
.bridge在幕後維護使用者調用的集合函數與定義小部件時提供的功能之間的映射。
第 8 章将進一步詳述 jquery ui 小部件和它提供的架構。第 9 章将探讨如何使用jquery ui的滑鼠子產品來實作一個圍繞滑鼠拖動功能的新元件。
2.1.6 jquery ui特效
jquery ui 另一個主要部分是網頁元素的一系列動畫特效。這些動畫大多數用來隐藏和顯現一個元素,比如blind(百葉窗)和drop(掉落);還有一部分用來吸引使用者的注意,比如highlight(高亮)和shake(晃動)。
可以通過擴充$.effects.effect(jquery 1.9之前的版本中是$.effects)把新的特效整合到jquery ui的特效進行中,然後這些特效就可以在jquery ui提供的effect函數或者show、hide、toggle 這些增強函數中使用了。每個特效都是一個函數。它把一個回調函數添加到目前元素的 fx 隊列中,前一個入隊的事件處理完畢後,這個回調函數會執行特效的動畫。
緩動(easings)定義了一個屬性值如何随着時間變化,可以被用在動畫中控制加速和減速。緩動雖然是jquery基本的一部分, 但隻提供了兩個執行個體—linear(線性)和swing(搖擺)。 jquery ui則提供了30種額外的緩動。開發者可以通過擴充$.easing添加自己的緩動,需要定義一個函數來傳回動畫過程中目前時間間隔(通常是0到1)的屬性變化值(通常也是0到1)。
想得到更多關于jquery ui特效的資訊,以及關于緩動的介紹,請參見第10章。
2.1.7 動畫屬性
jquery的動畫功能允許開發者改變一個標明元素的多個屬性值。這些屬性通常會影響元素的外觀,或者移動元素的位置,改變元素大小或邊框尺寸,或者調整它内容字型的大小。不過jquery隻能在數值類型的屬性(包括一個機關)上進行動畫。開發者需要添加自定義動畫來支援更加複雜的屬性。
通過擴充$.tween.prop-hooks來實作在其他屬性上的動畫,開發者需要提供兩個函數,一個擷取屬性值,另一個設定屬性值。在jquery 1.8 之前的版本中,開發者需要擴充$.fx.step,并提供一個函數來執行動畫的一幀。
第11章将介紹如何為jquery添加一個新的動畫。
2.1.8 ajax處理
ajax處理是jquery所提供的功能中的一個關鍵部分。它可以更容易地從伺服器擷取資訊并更新目前頁面,而且不用重新整理整個頁面。因為擷取的資料可能有多種格式,jquery使用預過濾器(prefilter)控制開始讀取資料之前的處理,使用傳輸器(transport)擷取基本的資料,使用轉換器(converter)把資料轉換為一個可用的格式。這些機制都可以被增強,以滿足特殊需求。圖2.2是一個标準的ajax調用成功的時序圖。
通過調用$.ajaxprefilter 函數,開發者可以定義一個在請求某個特定格式的資料(比如html、xml 或者 script)時被調用的函數。因為開發者的函數持有一個用來擷取資料的xmlhttprequest對象引用,是以開發者可以完全控制每個請求,包括取消請求。
開發者可以通過調用$.ajaxtransport函數為特定資料格式定義一個處理函數,處理真正擷取資料的過程,這樣開發者可以自定義如何通路資料(比如把圖像資料直接加載到image元素中)。預設使用xmlhttprequest對象。
最終,資料通常以文本格式傳回,但是在做一些初始化處理後可能會更有用,比如把xml解析為dom。通過調用$.ajaxsetup函數,開發者可以定義新的轉換器把結果轉換為另一種格式,并作為ajax請求的結果傳回。
關于如何通過定義自己的預過濾器、傳輸協定以及轉換器,請參見第12章。
2.1.9 事件處理
jquery允許開發者為選出的元素附加事件處理器,以響應使用者動作。在發生基本的滑鼠、鍵盤及狀态變化的事件時,這些處理器會被調用。如果有必要,開發者可以定義一個自定義事件來處理特殊的場景。
開發者可以通過擴充$.event.special添加一個自定義事件。每一個事件的定義都提供這一事件的類型,以及設定事件處理的函數,當這個事件不再需要時的解除安裝函數,以及在适當情況下觸發事件的函數。
第13章将詳細介紹如何建立和處理自定義事件。
**
2.1.10 驗證規則**
盡管驗證插件不是基本 jquery 庫的一部分,但是它是一個應用非常廣泛的插件,并且提供了擴充點,允許開發者添加新的驗證規則。這些規則可以和内置的那些規則(如required和number)一起使用,在送出表單前確定字段中填寫的資料的完整性和正确性。
開發者可以調用$.validator.addmethod來定義一個自定義驗證規則,開發者需要提供規則的名稱和一個驗證函數,如果驗證成功,則傳回true,否則傳回false。此時還需要指定一個驗證失敗時的錯誤資訊。開發者可以用$.validator.addclassrules函數使自己的新規則做到在元素的class屬性中指定名字就能自動驗證。
第14章将介紹如何定義開發者自己的驗證規則。