本節書摘來自異步社群《擴充 jquery》一書中的第6章,第6.1節,作者:【美】keith wood著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
因為函數插件不操作元素集合,也通常不與ui元件打交道,是以它們非常容易實作。盡管開發者可以把這些函數定義為獨立的javascript函數,但是把它們建立在jquery的命名空間中可以得到很多好處。這樣做可以降低全局命名空間的混亂,同時也降低了命名沖突的風險。它們通常也會使用jquery本身,把它們包含在jquery中能提供一緻的使用方式。它們還旨在提供更易用的功能以及隐藏跨浏覽器的差異(jquery背後的核心原則)。
作為函數插件的一個具體例子,開發者可以開發一個工具來協助自己網頁的本地化。它根據特定的語言和地區,隻加載必需的javascript檔案來定制開發者的站點。
6.1.1 本地化插件
基于5.5.2節中描述的本地化方案,這個工具假定相關的javascript檔案隻由它們的語言或地區碼來差別。當發生請求時,這個插件以語言和地區碼的升序來加載這些檔案,每個都覆寫前一個,這樣能得到給定的語言和地區的最佳比對結果。
例如,假定開發者有表6.1中的這些檔案。每一個都代表不同的語言和地區組合,并設定一個公共變量(greeting)來顯示消息。

為了把自己的頁面歡迎詞本地化為一種特定語言,開發者可以使用這段代碼:
這個插件将順序加載下列檔案,從最少比對到最佳比對——greeting.js,greeting- en.js,greeting-en-au.js——得到最比對的澳洲英語:“g’day”。如果請求的語言是加拿大英語(en-ca),因為沒有greeting-en-ca.js檔案,鍊條将在第二個檔案時停止(标準英語),它将産生歡迎語“good day”。如果請求了科薩語(xh),會得到預設歡迎詞:“hello”。
當這個檔案被加載和執行之後,就可以以通常的方式通路它們設定的那個變量。
如果調用localise()時沒有指定任何語言,它就使用浏覽器的預設語言。可以通過$.localise.default
language容易地得到這個預設語言。
本地化不僅限于顯示給最終使用者的文本,還可以影響顯示和外觀的其他方面。圖6.1展示了datepicker的一些本地化。
除了文本的變化,這些版本之間還有一些不同:
選擇年和月的下拉清單順序不同;
每個月曆中一周的開始日不同:法語是周一,日語是周日,阿拉伯語是周六;
阿拉伯語從右往左讀,其他兩個從左往右讀。
現在讀者應該知道這個插件的設計目的了,可以使用前一章中介紹的原則和架構來實作它。
6.1.2 架構代碼
盡管上一章中介紹的插件架構大部分都不适用于函數插件,但是還是有幾個應該保留的特性。開發者應該繼續堅持“利用作用域隐藏實作細節”和“不要依賴$與jquery的等同性”。解決方案與前面介紹的相同。
程式清單6.1 封裝插件代碼
通過定義一個匿名函數來建立一個作用域1,立即調用它來建立它的作用域并執行它内部的代碼2。通過定義一個參數$并且在調用時為其提供jquery的引用,保證了它們在函數體内指向同一個對象。
這個插件同時也遵守了“在所有地方使用唯一的名字”和“把一切都放在jquery對象中”原則。這裡不必支援鍊式調用,因為不牽扯jquery集合。當沒有指定語言時使用浏覽器的預設語言,這遵守了”使用合理的預設值”原則。
6.1.3 加載本地化檔案
程式清單6.2展示的localise函數實作了插件的主要功能:根據請求的語言和地區,加載一個或多個本地化檔案。
程式清單6.2 聲明插件函數
通過把這個函數聲明為一個屬性,把它直接附加到jquery中1。然後就可以在開發者的頁面上通過 jquery 對象來通路這個函數。不需要為它選擇任何操作元素,因為它應用于整個頁面。
這個函數通過多個參數來改變它的行為。除了第一個參數,其餘都是可選的。如果沒有設定,則使用一個合适的預設值。使用它們的類型來确定它們所代表的含義。程式清單6.3展示了如何處理這些參數。
開發者必須指定一個(string)或一組(string)包名,以供這個函數使用。因為其餘的參數都是可選的,代碼就必須能區分它們。第二個參數是一個可選的語言代碼(string)或者一組設定(object),它的每個屬性都是一個獨立的參數。為了使後續的處理更容易,所有單獨的參數值都被收集到一個設定對象中,就像最初就提供了這個對象一樣。如果第二個參數不是這些類型,這些參數被順序移動1并繼續處理下一個。
其餘的參數包括一個用來指定是否需要重新加載基礎本地化檔案的可選标志(boolean)2,一個(string)或一組(string)可選的路徑用來指定從哪裡找到本地化檔案3,一個可選的逾時時間(number)4,一個可選的異步标志(boolean)5,以及一個可選的加載完成時的回調函數。缺失的參數被設定為預設值。
程式清單6.3 參數的預設值和标準化
根據參數中提供的設定對象(覆寫所有預設值)或者單個參數值來建立一個累積設定對象6。檢查path是一個還是多個路徑,然後把它轉換為後面需要的格式7。把後面ajax需要用到的一些選項收集起來以便于後續使用8。
當參數處理完成之後,這個插件接下來依次處理所有指定的包。
程式清單6.4 加載本地化檔案
開發者定義了一個内部函數1來處理單個包。每個都加載為基礎檔案(如果設定了加載基礎)2,然後加上2字元的語言代碼3,最後再加上一個5字元的語言和地區代碼(如果有)4。這些檔案被放在一個隊列中以便順序讀取。
使用jquery内置的ajax函數來加載單個檔案5,從隊列中的第一個檔案開始,指定傳回内容是“script”并以這個類型執行。因為預設使用同步加載(為了保證後續的代碼可以依賴傳回的内容),是以有一個逾時時間。或者可以在調用localise時指定一個額外的參數來使用異步加載,同時指定一個在加載完成時調用的回調函數6。如果隊列中還有其他檔案,則遞歸調用處理下一個7。
當單個包和其中檔案的處理流程定義好之後,找到需要的語言和地區8,然後依次加載每個包9。
為了實作這個插件所宣揚的功能,這裡定義了另一個函數來提供地方化的版本:
本書的網站上可以下載下傳到這個插件的完整代碼。