欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jQuery創(chuàng)建自己的插件(自定義插件)的方法

 更新時(shí)間:2010年06月10日 21:34:10   作者:  
在該系列之前的文章使用 jQuery:UI 項(xiàng)目中,我介紹了使用 jQuery 代碼中的插件來(lái)提高 web 應(yīng)用程序的效率。
但必須知道,這些插件不是自己憑空產(chǎn)生的,它們是由開(kāi)發(fā)人員編寫(xiě)、測(cè)試并完善的,這些人員為 jQuery 社區(qū)奉獻(xiàn)了自己的業(yè)余時(shí)間。我們做這些都是免費(fèi)的,是出于對(duì)自己代碼的熱愛(ài)。本文主要關(guān)注您如何回報(bào)這個(gè)偉大的社區(qū),即如何編寫(xiě)自己的插件并上傳到 jQuery 的插件頁(yè)面。這可以讓所有人使用您創(chuàng)建的插件,可以讓整個(gè) jQuery 開(kāi)發(fā)社區(qū)變得更好。今年您也做出自己的貢獻(xiàn)吧。

在編寫(xiě)本文中的插件時(shí),我發(fā)現(xiàn)插件的創(chuàng)建過(guò)程以及用來(lái)創(chuàng)建它的框架非常簡(jiǎn)單明了。困難的地方在于想一些其他人還沒(méi)有做過(guò)的事情,并編寫(xiě)一些能真正完成某些操作的 JavaScript 代碼。由于插件結(jié)構(gòu)簡(jiǎn)單明了,對(duì)于新手它簡(jiǎn)單易學(xué),對(duì)于高手它很靈活,因此插件的數(shù)量急速上升。

當(dāng)然,在研究本文所涉及的內(nèi)容時(shí),我還發(fā)現(xiàn)每個(gè)作者編寫(xiě)插件的風(fēng)格都不同,jQuery 允許好幾種不同的插件編寫(xiě)風(fēng)格。在本文中,我集中介紹最簡(jiǎn)單的一種風(fēng)格,以及 jQuery 本身推薦的一種風(fēng)格,插件彈出后您就會(huì)看到差別或不同的選項(xiàng)。

描述插件

創(chuàng)建插件的第 1 步當(dāng)然是想一個(gè)好點(diǎn)子。像大部分點(diǎn)子一樣,其他人總會(huì)給您創(chuàng)造機(jī)會(huì)。以我在本文中開(kāi)發(fā)的插件為例,它不是什么新穎的概念,但在我撰寫(xiě)文本的時(shí)候,jQuery 插件社區(qū)還找不到該插件。我知道我個(gè)人會(huì)從該插件中受益良多。

我的插件是一個(gè) NumberFormatter 插件。處理服務(wù)器端代碼(比如 Java™ 或 PHP)和國(guó)際化的用戶(hù)應(yīng)該很熟悉數(shù)字格式化。眾所周知,并非每個(gè)人都用相同的方式格式化數(shù)字。例如,并非每個(gè)人都使用 “里” 來(lái)度量距離。在美國(guó),數(shù)字的寫(xiě)法可能是 “1,250,500.75”(這個(gè)數(shù)字是從我的稅收表上抄來(lái)的),但在其他國(guó)家的寫(xiě)法可能完全不同:德國(guó)是 “1.250.500,75”,法國(guó)是 “1 250 500,75”,瑞士是 “1'250'500.75”,日本是 “125,0500.75”。數(shù)字完全相同,但是在向 web 應(yīng)用程序用戶(hù)展示時(shí)使用不同的格式。

因此,問(wèn)題歸結(jié)到,當(dāng)編寫(xiě)一個(gè)國(guó)際化應(yīng)用程序時(shí),如何向不同國(guó)家的人展示這些數(shù)字?當(dāng)然,解決方案是使用服務(wù)器端格式化,這種解決辦法非常常見(jiàn)。Java 有一個(gè)健壯的格式化庫(kù),使數(shù)字的格式化變得非常簡(jiǎn)單。當(dāng)使用數(shù)字在服務(wù)器上設(shè)置頁(yè)面時(shí),服務(wù)器負(fù)責(zé)處理這些數(shù)字。但是,很多時(shí)候數(shù)字可能不在服務(wù)器上,因此您需要一種方法在客戶(hù)機(jī)上格式化數(shù)字,而不需要與服務(wù)器會(huì)話。

我在這里描述的典型用例如下。您的 web 應(yīng)用程序中有一個(gè)輸入字段,要求用戶(hù)輸入他們的薪水。在美國(guó),用戶(hù)可能以各種格式輸入 “$65000”、“65,000”、“65000” 和 “65,000.00”。所有這些數(shù)字都是相同的,但是您需要控制這些數(shù)字在屏幕上的顯示方式,這樣才能提供更好的用戶(hù)體驗(yàn)。您可以在輸入數(shù)字之后調(diào)用服務(wù)器,但是如果有許多使用不同格式的數(shù)字字段就太麻煩了。此外,如果您可以在客戶(hù)端處理該問(wèn)題,并向用戶(hù)提供即時(shí)反饋,那么就不需要這樣做了。

因此,我建立了一個(gè)空缺,之后我將嘗試使用 JavaScript/jQuery 功能填補(bǔ)這一空缺。我的插件將在客戶(hù)機(jī)上提供數(shù)字格式化,為其他人提供一種國(guó)際化 web 應(yīng)用程序的方式,且無(wú)需與服務(wù)器會(huì)話。作為額外的功能,我的插件還可以提供反向操作;該插件使開(kāi)發(fā)人員能夠解析數(shù)字,從格式化的文本字符串中獲取數(shù)字。這還可以應(yīng)用于客戶(hù)機(jī)上的數(shù)字操作。此外,我將模擬 JavaDecimalFormatter類(lèi)中的功能,以維護(hù)執(zhí)行數(shù)字格式化的客戶(hù)端代碼和標(biāo)準(zhǔn)服務(wù)器端方法之間的通用性。

第 1 步結(jié)果:我發(fā)現(xiàn)了一個(gè)插件需求,然后定義了對(duì)于該需求我可以填補(bǔ)的空缺。

插件規(guī)則

jQuery 團(tuán)隊(duì)建立了許多希望插件作者都能遵守的通用規(guī)則,為插件用戶(hù)創(chuàng)建一個(gè)通用而可信的環(huán)境??紤]到 jQuery 團(tuán)隊(duì)比我聰明多了,我沒(méi)有理由違背這些規(guī)則,對(duì)不對(duì)?出于該原因,我在此列出這些規(guī)則,并且在插件的每一步都盡量遵守這些規(guī)則。

  • 文件命名為 “jquery.<your plug-in name>.js
    這是有道理的,因?yàn)槟M脩?hù)查看文件時(shí)立即知道這是一個(gè) jQuery 插件以及這是哪個(gè)插件。

    檢查完畢。我的插件將命名為 “jquery.numberformatter.js”。

  • 所有新方法都附加到 jQuery.fn 對(duì)象,所有新功能都附加到 jQuery 對(duì)象
    現(xiàn)階段這可能有點(diǎn)難以理解,在下一節(jié)我將討論更多內(nèi)容,因?yàn)檫@是實(shí)際編碼過(guò)程中最重要的規(guī)則。

    檢查完畢。我的方法/函數(shù)將僅附加到這兩個(gè)對(duì)象。

  • this” 用于引用 jQuery 對(duì)象
    這有利于插件作者的編寫(xiě),它讓所有插件作者在引用 “this” 時(shí)都知道將從 jQuery 收到哪個(gè)對(duì)象。

    檢查完畢。我將僅使用 “this” 引用 jQuery 對(duì)象。

  • 插件中定義的所有方法/函數(shù)的末尾都必須帶有一個(gè) “;”(分號(hào)),否則將不利于代碼的最小化。
    因?yàn)檫@是最小化 JavaScript 文件的最佳實(shí)踐,大于最小值會(huì)很糟糕,您的插件有可能很快就被拋棄。

    檢查完畢。所有的方法/函數(shù)都將以 “;” 結(jié)尾。

  • 除有特別注明外,所有方法都必須返回 jQuery 對(duì)象
    jQuery 方法的順序鏈 (daisy-chaining) 非常著名,如果您編寫(xiě)打破鏈條的插件,它就一定會(huì) “打破鏈條”。

    檢查完畢。我的format()方法將返回 jQuery 對(duì)象,雖然我的parse()方法沒(méi)有返回 jQuery 對(duì)象,但我在很多地方都注明該函數(shù)打破了鏈條。(畢竟,它不可能返回一個(gè) Number 對(duì)象而不打破鏈條)。

  • 您應(yīng)該總是使用this.each()迭代匹配的元素,這是一種可靠而有效地迭代對(duì)象的方式。
    出于性能和穩(wěn)定性考慮,他們推薦所有的方法都使用它迭代匹配的元素。

    檢查完畢。我的方法都將只使用該方法迭代匹配的元素。

  • 總是在插件代碼中使用 “jQuery” 而不是 “$”
    這很重要,它使與 “$” 有沖突的用戶(hù)(那些使用另一個(gè) JavaScript 庫(kù)的用戶(hù))能夠使用 “var JQ = jQuery.noConflict();” 函數(shù)更改他們的 jQuery 別名(pseudonym)。但是,在我查看許多插件時(shí),我發(fā)現(xiàn)該規(guī)則常常得不到遵守,這太不幸了。如果開(kāi)發(fā)人員需要更改 jQuery 別名,那么很可能意味著該插件要被棄用了。

    檢查完畢。在我的插件中,我將僅使用 jQuery 而不是它的別名 “$”。

好了,這些就是在插件代碼中必須遵守的規(guī)則和建議。真正的問(wèn)題在于,它們實(shí)際上是強(qiáng)制性的,因?yàn)槿绻蛔袷剡@些插件規(guī)則,那么您的插件就得不到廣泛應(yīng)用,而且還會(huì)得到不好的反饋。結(jié)果該插件很快就沒(méi)有人使用了,您所花費(fèi)的時(shí)間都將白費(fèi)。因此,遵守這些規(guī)則非常重要。這不僅能幫助您鶴立雞群,保證您代碼的統(tǒng)一性,還能增加插件的成功幾率。

第 2 步結(jié)果:我將遵守創(chuàng)建 jQuery 插件的所有規(guī)則

編寫(xiě)插件

現(xiàn)在可以開(kāi)始編寫(xiě)代碼了!開(kāi)始編寫(xiě)插件的第一步是確定如何組織您的插件。開(kāi)始有兩種選擇:您希望它是一個(gè)方法還是一個(gè)函數(shù)?“它們有區(qū)別嗎?”您可能會(huì)這樣問(wèn)。

正如我上面提到的,方法需要附加到 jQuery.fn 對(duì)象,函數(shù)需要附加到 jQuery 對(duì)象。這樣一切都清楚了,不是嗎?如果您對(duì) jQuery 相對(duì)不太了解,那么可能還不是很清楚。您可以這樣考慮。方法使代碼能夠迭代所有傳入插件的選定元素。因此,插件可以接收任何類(lèi)型的 HTML 元素,由插件決定如何處理每個(gè)元素。因此,插件方法可以接收任何 jQuery 選擇器,所有從 “p” 到 “#mySpecificPageElement” 的內(nèi)容。如果您希望插件更加靈活,允許用戶(hù)傳入任何類(lèi)型的頁(yè)面元素,那么最好使用方法。插件開(kāi)發(fā)人員應(yīng)該負(fù)責(zé)正確地處理所有內(nèi)容。相比之下,函數(shù)使用任何選定元素作為參數(shù)。函數(shù)可以簡(jiǎn)單地應(yīng)用于整個(gè)頁(yè)面。這也由插件開(kāi)發(fā)人員負(fù)責(zé)處理,開(kāi)發(fā)人員必須定義他們希望與插件交互的頁(yè)面元素,并忽略其他元素。讓我們?cè)诖a中看看不同之處。


清單 1. jQuery 插件方法/函數(shù)

// This is a method because you can pass any type of selector to the method and it
// will take some action on the results of the selector. In this case, it will
// doSomething() on the page element with an ID of myExample
$("#myExample").doSomething();

// This is also a method, even though you are passing the entire page body to
// the method, because you are still passing a selector
$("body").doSomethingElse();

 

// This is a function, because you are NOT passing any selector to the function
// The plug-in developer must determine what page elements they want to take action on.
// This is usually accomplished by the plug-in developer requiring the page elements
// to contain a certain class name.

<div class="anotherThing">

// This hypothetical plug-in developer would document that his plug-in only works
// on elements with the class "anotherThing"
$.anotherThing();

 

從這些描述中判斷,插件使用的似乎是方法,因?yàn)槟枰層脩?hù)告訴您他們希望格式化哪些頁(yè)面元素。清單 2 展示了現(xiàn)在插件的代碼。


清單 2. 方法定義

jQuery.fn.format = function();

 

// You would call your plug-in like this (at this point)
$("#myText").format();

 

當(dāng)然,您的函數(shù)不可能是放之四海而皆準(zhǔn)的插件,因?yàn)槟幚淼氖菄?guó)際化情況,無(wú)法自動(dòng)指出希望格式化文本的國(guó)家或者需要的格式。因此,您必須稍微修改插件以接收某些選項(xiàng)。格式化方法中需要兩個(gè)選項(xiàng):數(shù)字應(yīng)該使用的格式(例如,#,### 以及 #,###.00)和本地語(yǔ)言環(huán)境(本地語(yǔ)言環(huán)境是一個(gè)簡(jiǎn)單的 2 字符國(guó)家代碼,用于確定要使用的國(guó)際數(shù)字格式)。

您還需要讓插件盡可能的易于使用,因?yàn)槟仨毺岣卟寮某晒茁?。這意味著您應(yīng)該繼續(xù)定義一些默認(rèn)的選項(xiàng),使用戶(hù)在不想傳入選項(xiàng)時(shí)不需要這樣做。我編寫(xiě)插件的所在地是美國(guó),這里使用的是世界上最常見(jiàn)的數(shù)字格式,我的默認(rèn)語(yǔ)言環(huán)境是 “us”,格式默認(rèn)為 “#,###.00”,因此貨幣自然要使用該默認(rèn)值。

 

 

清單 3. 允許在插件中使用選項(xiàng)


jQuery.fn.format = function(options) {

 

// the jQuery.extend function takes an unlimited number of arguments, and each
// successive argument can overwrite the values of the previous ones.
// This setup is beneficial for defining default values, because you define
// them first, and then use the options passed into the method as the
// second argument. This allows the user to override any default values with their
// own in an easy-to-use setup.
var options = jQuery.extend( {

format: "#,###.00",
locale: "us"

}, options);

 

創(chuàng)建插件框架的最后一步是正確處理傳入方法的選定元素?;叵胍幌律侠鷷?huì)發(fā)現(xiàn),選定元素可以是單頁(yè)面元素,或者是多頁(yè)面元素。您必須等效地處理它們。同樣,回想一下 jQuery 插件規(guī)則,"this" 對(duì)象只能引用 jQuery 對(duì)象。因此,您有一個(gè)對(duì)傳入方法的 jQuery 選定元素的引用,現(xiàn)在需要迭代它們。同樣,回顧規(guī)則讓我們知道,每個(gè)插件方法都應(yīng)該返回 jQuery 對(duì)象。當(dāng)然,您知道 jQuery 對(duì)象就是 "this",因此在方法中返回 this 完全沒(méi)有問(wèn)題。讓我們看看如何在代碼片段中實(shí)現(xiàn)迭代每個(gè)選定元素并返回 jQuery 對(duì)象。


清單 4. 處理 jQuery 對(duì)象


jQuery.fn.format = function(options) {

 

var options = jQuery.extend( {

format: "#,###.00",
locale: "us"

}, options);

// this code snippet will loop through the selected elements and return the jQuery object
// when complete
return this.each(function(){
// inside each iteration, you can reference the current element by using the standard
// jQuery(this) notation
// the rest of the plug-in code goes here
});

 

由于實(shí)際插件本身不是本文的重點(diǎn),我不對(duì)此進(jìn)行詳細(xì)闡述,但是您可以在本文的插件代碼附件中看到全部?jī)?nèi)容(請(qǐng)參見(jiàn) 下載)。如果您決定編寫(xiě)函數(shù)而不是方法,我還將向您展示一個(gè)樣例,介紹如何設(shè)置插件架構(gòu)。


清單 5. 使用函數(shù)的示例插件


jQuery.exampleFunction = function(options) {

 

var options = jQuery.extend( {

// your defaults

}, options);

jQuery(".exampleSelector").each(function(){

});

});

 

調(diào)優(yōu)插件

網(wǎng)上關(guān)于初級(jí)插件的大部分文章都到此為止了,這時(shí)它們會(huì)讓您采用基本的插件格式并運(yùn)行。但是,這種基本架構(gòu)也太 “基本” 了。在編寫(xiě)插件時(shí)還必須考慮另一件重要的事情,給您插件增色所需要的內(nèi)容遠(yuǎn)不止一個(gè)初級(jí)插件那么簡(jiǎn)單。再多增加兩個(gè)步驟,您就能將初級(jí)插件轉(zhuǎn)換為中級(jí)插件。

調(diào)優(yōu) #1 - 讓內(nèi)部方法私有化

在任何面向?qū)ο蟮木幊陶Z(yǔ)言中,您會(huì)發(fā)現(xiàn)創(chuàng)建運(yùn)行重復(fù)代碼的外部函數(shù)非常方便。在我創(chuàng)建的 NumberFormatter 插件中,有一個(gè)這種代碼的樣例 —— 該代碼決定向函數(shù)傳遞哪個(gè)地理位置,以及要使用哪些字符作為小數(shù)點(diǎn)和分組符。format() 方法和 parse() 方法中都需要該代碼,任何一個(gè)初級(jí)程序員都會(huì)告訴您這屬于它自己的方法。但是,這會(huì)出現(xiàn)一個(gè)問(wèn)題,因?yàn)槟幚淼氖?jQuery 插件:如果您使用 JavaScript 中的定義將它作為自己的函數(shù),那么任何人都可以為任何目的使用腳本調(diào)用該方法。這不是該函數(shù)的目的,我更傾向于不調(diào)用它,因?yàn)樗鼉H用于內(nèi)部工作。那么,讓我們看看如何將該函數(shù)私有化。

這種私有方法問(wèn)題的解決方案稱(chēng)為 Closure,它可以有效地從外部調(diào)用關(guān)閉整個(gè)插件代碼,附加到 jQuery 對(duì)象的除外(那些是公共方法)。通過(guò)這種設(shè)計(jì),您可以將任何代碼放入插件中,不用擔(dān)心被外部腳本調(diào)用。通過(guò)將插件方法附加到 jQuery 對(duì)象,您可以有效地將它們變?yōu)楣卜椒?,而讓其他的函?shù)/類(lèi)私有化。清單 6 展示了實(shí)現(xiàn)該操作所需的代碼。


清單 6. 私有化函數(shù)


// this code creates the Closure structure
(function(jQuery) {

 

// this function is "private"
function formatCodes(locale) {
// plug-in specific code here
}; // don't forget the semi-colon

// this method is "public" because it's attached to the jQuery object
jQuery.fn.format = function(options) {

var options = jQuery.extend( {

format: "#,###.00",
locale: "us"

},options);

return this.each(function(){
var text = new String(jQuery(this).text());
if (jQuery(this).is(":input"))
text = new String(jQuery(this).val());

// you can call the private function like any other function
var formatData = formatCodes(options.locale.toLowerCase());

// plug-in-specific code here
});
}; // don't forget the semi-colon to close the method

// this code ends the Closure structure
})(jQuery);

 


調(diào)優(yōu) #2 - 讓插件的默認(rèn)值可覆蓋

調(diào)優(yōu)插件的最后一步是讓它可以覆蓋默認(rèn)值。畢竟,如果德國(guó)的開(kāi)發(fā)人員下載了該插件,而且了解他的所有 web 應(yīng)用程序用戶(hù)希望使用德文版本,那么您應(yīng)該讓他能夠使用一行代碼修改默認(rèn)語(yǔ)言環(huán)境,而不是要他在每個(gè)方法調(diào)用中都修改一遍。這樣您的插件才會(huì)非常方便,因?yàn)橐粋€(gè) web 應(yīng)用程序不太可能使用不同的國(guó)際化格式向用戶(hù)展示數(shù)字。您在網(wǎng)頁(yè)上看一下就知道,所有數(shù)字都是使用同一個(gè)語(yǔ)言環(huán)境的格式。

該步驟要求您修改某處代碼,因此您將看到讓插件最為耀眼的一步。


清單 7. 覆蓋默認(rèn)值

 

jQuery.fn.format = function(options) {
// Change how you load your options in to take advantage of your overridable defaults
// You change how your extend() function works, because the defaults
// are globally defined, rather than within the method. If you didn't use the
// {} as the first argument, you'd copy the options passed in over the defaults, which is
// undesirable. This {} creates a new temporary object to store the options
// You can simply call the defaults as an object within your plug-in
var options = jQuery.extend({},jQuery.fn.format.defaults, options);

return this.each(function(){

// rest of the plug-in code here

// define the defaults here as an object in the plug-in
jQuery.fn.format.defaults = {
format: "#,###.00",
locale: "us"
}; // don't forget the semi-colon


這是創(chuàng)建插件的最后一個(gè)步驟!這樣您就有了一個(gè)不錯(cuò)的插件,可以進(jìn)行最后的測(cè)試了。清單 8 展示了您可以放入本文的完整插件,以便您查看這些部分是如何變?yōu)橐粋€(gè)整體的。此外還包含了 parse() 函數(shù),到目前為止我還沒(méi)有討論過(guò)該函數(shù),但是它包含在插件中(我沒(méi)有詳細(xì)介紹插件處理格式化的部分,因?yàn)樗鼈儾辉诒疚挠懻撝?。樣例中包含了該部分,插件本身?dāng)然也有)。


清單 8. NumberFormatter 插件

(function(jQuery) {

 

function FormatData(valid, dec, group, neg) {
this.valid = valid;
this.dec = dec;
this.group = group;
this.neg = neg;
};

function formatCodes(locale) {
// format logic goes here
return new FormatData(valid, dec, group, neg);
};

jQuery.fn.parse = function(options) {

var options = jQuery.extend({},jQuery.fn.parse.defaults, options);

var formatData = formatCodes(options.locale.toLowerCase());

var valid = formatData.valid;
var dec = formatData.dec;
var group = formatData.group;
var neg = formatData.neg;

var array = [];
this.each(function(){

var text = new String(jQuery(this).text());
if (jQuery(this).is(":input"))
text = new String(jQuery(this).val());


// now we need to convert it into a number
var number = new Number(text.replace(group,'').replace(dec,".").replace(neg,"-"));
array.push(number);
});

return array;
};

jQuery.fn.format = function(options) {

var options = jQuery.extend({},jQuery.fn.format.defaults, options);

var formatData = formatCodes(options.locale.toLowerCase());

var valid = formatData.valid;
var dec = formatData.dec;
var group = formatData.group;
var neg = formatData.neg;

return this.each(function(){
var text = new String(jQuery(this).text());
if (jQuery(this).is(":input"))
text = new String(jQuery(this).val());

// formatting logic goes here

if (jQuery(this).is(":input"))
jQuery(this).val(returnString);
else
jQuery(this).text(returnString);
});
};

jQuery.fn.parse.defaults = {
locale: "us"
};

jQuery.fn.format.defaults = {
format: "#,###.00",
locale: "us"
};

})(jQuery);


測(cè)試插件

創(chuàng)建插件的最后一步是全面測(cè)試它。用戶(hù)在插件中發(fā)現(xiàn) bug 會(huì)讓他們很惱火。用戶(hù)不會(huì)去修復(fù)它,他們會(huì)快速放棄使用它。如果有幾個(gè)這類(lèi)用戶(hù)再加上一些糟糕的評(píng)論,您的插件很快就會(huì)石沉大海。此外,這是一個(gè)很好的互惠行為 —— 您希望自己使用的插件都經(jīng)過(guò)了很好的測(cè)試,那么您也應(yīng)該提供經(jīng)過(guò)良好測(cè)試的插件。

我創(chuàng)建了一個(gè)快速測(cè)試結(jié)構(gòu)來(lái)測(cè)試我的插件(不需要單元測(cè)試庫(kù)),該結(jié)構(gòu)創(chuàng)建了許多跨區(qū),跨區(qū)中是一些數(shù)字,緊接數(shù)字后面的是該數(shù)字的正確格式。JavaScript 測(cè)試對(duì)數(shù)字調(diào)用格式,然后比較格式化的數(shù)字與想要的結(jié)果,如果失敗則顯示為紅色。通過(guò)該測(cè)試,我可以設(shè)置不同的測(cè)試用例,測(cè)試所有可能的格式(我已經(jīng)這樣做了)。我將測(cè)試頁(yè)面附加到樣例 下載 中,以便您為測(cè)試自己插件找到一個(gè)可能的解決方案,利用 jQuery 進(jìn)行測(cè)試。

查看完成的插件

讓我們看看運(yùn)行中的新 NumberFormatter。我已經(jīng)創(chuàng)建了一個(gè)簡(jiǎn)單的 web 應(yīng)用程序,您可以查看 NumberFormatter 插件如何滿足您的應(yīng)用程序。

 

圖 1. 運(yùn)行中的 NumberFormatter
 

這個(gè) Web 應(yīng)用程序很簡(jiǎn)單,也很直接。當(dāng)用戶(hù)離開(kāi)文本字段時(shí)(輸入了薪水、住宅、子女信息之后),NumberFormatter 插件將相應(yīng)地格式化其輸入的信息。該插件使 Web 應(yīng)用程序能夠向用戶(hù)展示統(tǒng)一格式的數(shù)字。還要注意,該 web 應(yīng)用程序是為德國(guó)用戶(hù)格式化的,因此小數(shù)點(diǎn)和分組符號(hào)與美國(guó)用戶(hù)不一樣(關(guān)于這一點(diǎn),請(qǐng)讓我展示如何更改默認(rèn)值)。


清單 9. 運(yùn)行中的 NumberFormatter

$(document).ready(function() {

 

// use the AlphaNumeric plug-in to limit the input
$(".decimal").decimal();
$(".numeric").numeric();

// you want to change the defaults to use the German locale
// this will change the default for every method call on the
// entire page, so you won't have to pass in the "locale"
// argument to any function
$.fn.format.defaults.locale = "de";
$.fn.parse.defaults.locale = "de";

// when the salary field loses focus, format it properly
$("#salary").blur(function(){
$(this).format({format:"#,###.00"});
});

// when the house field loses focus, format it properly
$("#houseWorth").blur(function(){
$(this).format({format:"#,###"});
});

// when the kids field loses focus, format it properly
$("#kids").blur(function(){
$(this).format({format:"#"});
});

// calculate the tax
$("#calculate").click(function(){
// parse all the numbers from the fields
var salary = $("#salary").parse();
var house = $("#houseWorth").parse();
var kids = $("#kids").parse();
// make some imaginary tax formula
var tax = Math.max(0,(0.22*salary) + (0.03*house) - (4000*kids));
// place the result in the tax field, and then format the resulting number
// you need one intermediate step though, and that's the "formatNumber" function
// because all numbers in JavaScript use a US locale when made into a String
// you need to convert this Number into a German locale String before
// calling format on it.
// So, the steps are:
// 1) the tax is a Number that looks like 9200.54 (US locale)
// 2) formatNumber converts this to a String of 9200,54 (German locale)
// 3) put this String in the #tax field
// 4) Call format() on this field
$("#tax").text($.formatNumber(tax)).format({format:"#,###"});
});

});


在結(jié)束之前,關(guān)于 NumberFormatter 插件還有幾件事情需要指出。首先,該插件是第一個(gè) 1.0.0 發(fā)行版,因此我希望將來(lái)進(jìn)行擴(kuò)展,包含更多 Java DecimalFormatter 中的格式化功能。包括支持貨幣、科學(xué)計(jì)數(shù)法和百分比。它還對(duì)負(fù)數(shù)和正數(shù)包含不同的格式化規(guī)則,負(fù)數(shù)不是簡(jiǎn)單的 “-”(例如,對(duì)負(fù)數(shù)使用 (5,000),在會(huì)計(jì)中是這樣做的)。最后,一個(gè)好的格式器應(yīng)該支持格式中的任何字符,而僅它忽略不屬于保留字符的部分。這都是我近期想添加的功能,希望該插件變得更加健壯。

獲取用戶(hù)的語(yǔ)言環(huán)境

最后一個(gè)問(wèn)題與 jQuery 無(wú)關(guān),但是使用該插件時(shí)可能會(huì)出現(xiàn) —— 如何獲取用戶(hù)的語(yǔ)言環(huán)境?這個(gè)問(wèn)題提得很好,因?yàn)槟壳笆褂?JavaScript 沒(méi)有辦法獲取該信息。您需要?jiǎng)?chuàng)建一個(gè) JavaScript Bridge 來(lái)實(shí)現(xiàn)該目的。什么是 JavaScript Bridge?我的意思是您可以建立一個(gè)簡(jiǎn)單的設(shè)計(jì)模式將值從服務(wù)器端代碼傳入 JavaScript 代碼。清單 10 展示了您可以使用 Java 在 JSP 頁(yè)面做到這一點(diǎn)。

 

 

清單 10. 獲取用戶(hù)的語(yǔ)言環(huán)境

<%

 

// the request object is built into JSPs
// unfortunately, it's not any easier
// tested on FF, IE, Safari, Chrome
String locale = "us"; // or your default locale
String accLang = request.getHeader("Accept-Language");
if (accLang.length() > 5)
{
accLang = accLang.substring(0,5);
locale = accLang.substring(accLang.indexOf("-")+1);
}

%>

$(document).ready(function() {

// take advantage of the ability to override defaults by using the JavaScript
// Bridge here. Then your page can use the format() and parse() functions
// elsewhere in the page without modifying them for a user's locale.
$.fn.format.defaults.locale = "<%=locale%>";
$.fn.parse.defaults.locale = "<%=locale%>";

});


共享插件

最后,編寫(xiě)和測(cè)試插件都做完了。最后一步是與他人共享該插件,并將它上傳到 jQuery 網(wǎng)站的插件存儲(chǔ)庫(kù)。

  • 轉(zhuǎn)到 jQuery 網(wǎng)站的插件頁(yè)面,在左導(dǎo)航欄,單擊 Login/Register 然后單擊 Create New Account。如果已經(jīng)有一個(gè)帳戶(hù),請(qǐng)登錄;如果沒(méi)有,則創(chuàng)建一個(gè)新帳戶(hù)。
  • 驗(yàn)證通過(guò)后,左導(dǎo)航將出現(xiàn)一些選項(xiàng)。其中有一個(gè) “Add plug-in”。
  • 導(dǎo)航插件創(chuàng)建頁(yè)面。因?yàn)槟荒苁褂?jQuery 1.2 測(cè)試該插件,您應(yīng)該將其作為一個(gè)兼容版本包含在內(nèi)。花一些時(shí)間為插件寫(xiě)一個(gè)好標(biāo)題以及一個(gè)好的描述。畢竟,現(xiàn)在是向其他用戶(hù)推銷(xiāo)該插件的時(shí)候了,您需要讓自己與眾不同。盡量講出該插件的好處。
  • 該插件需要您提供插件主頁(yè)。雖然您創(chuàng)建了插件,但很可能沒(méi)有插件主頁(yè)。幸運(yùn)的是,如果您沒(méi)有自己的服務(wù)器保存插件,Google 很樂(lè)于為開(kāi)源項(xiàng)目提供空間。我選擇在 Google Code 中放置該插件。要建立自己的 Google Code 項(xiàng)目,只需要訪問(wèn) code.google.com 然后按照注冊(cè)流程注冊(cè)即可。
  • 按下 Submit 之后您的插件就創(chuàng)建好了!
    恭喜,您的插件現(xiàn)在是 jQuery 插件社區(qū)的一部分了,您現(xiàn)在正式成為開(kāi)源項(xiàng)目的貢獻(xiàn)者之一。給自己一個(gè) 5 星評(píng)級(jí)以獎(jiǎng)勵(lì)自己吧!因?yàn)槟档茫?

結(jié)束語(yǔ)

在本文中,我主要介紹如何為 jQuery JavaScript 框架創(chuàng)建插件。我從頭開(kāi)始,構(gòu)思了一個(gè)想法并將其付諸實(shí)現(xiàn),介紹了創(chuàng)建該插件要使用的幾個(gè)步驟。然后,我閱讀了 jQuery “戒律”,它是為確保插件的一致性而設(shè)置的插件規(guī)則。我還在文章中提醒這些規(guī)則,因?yàn)槲铱吹皆S多規(guī)則在插件中都沒(méi)有得到遵守,尤其是只能在插件中使用 “jQuery” 而不是 “$”(當(dāng)然,我遵守了該規(guī)則)。

介紹了插件的背景,以及編寫(xiě)插件的規(guī)則之后,您了解了基本的插件框架以及在插件中編寫(xiě)方法與編寫(xiě)函數(shù)的不同。方法應(yīng)該在采用選定元素作為參數(shù)并對(duì)其執(zhí)行某些操作時(shí)使用。提供頁(yè)面元素的任務(wù)由調(diào)用方法的人負(fù)責(zé)。另一方面,函數(shù)應(yīng)該在對(duì)選定元素不感興趣時(shí)使用,因?yàn)槟呀?jīng)知道要執(zhí)行操作的頁(yè)面元素。提供頁(yè)面元素的任務(wù)由編寫(xiě)該函數(shù)的開(kāi)發(fā)人員負(fù)責(zé)。這兩種形式的插件都是有效的,僅在在插件需求上有所不同。最后,查看設(shè)置默認(rèn)選項(xiàng)的基本方式以及如何讓用戶(hù)提供自己的選項(xiàng)。

本文的下一步是為插件提供一些亮點(diǎn),以增加它的先進(jìn)性。該步驟給整個(gè)插件畫(huà)上了句號(hào),有效地創(chuàng)建了私有函數(shù)和公共函數(shù)。我創(chuàng)建了一些在插件內(nèi)部調(diào)用的函數(shù),以便插件外部的人無(wú)法調(diào)用它們。您還可以看到如何向插件用戶(hù)展示默認(rèn)值,讓用戶(hù)定義他們自己的默認(rèn)值,輕松實(shí)現(xiàn)編碼。

最后,在樣例 web 應(yīng)用程序中使用插件展示它的行為。本文的最后一部分是這些努力工作的最終成果 —— 您需要將插件上傳到 jQuery 插件社區(qū)站點(diǎn),讓它成為 JavaScript 庫(kù)的一部分。 

相關(guān)文章

  • jquery 簡(jiǎn)單應(yīng)用示例總結(jié)

    jquery 簡(jiǎn)單應(yīng)用示例總結(jié)

    jquery 想必大家早已如雷貫耳,本文整理了一些在實(shí)際應(yīng)用中比較常見(jiàn)的功能片段,感興趣的朋友可以學(xué)習(xí)下哦,需要改進(jìn)的地方希望大家不惜指教
    2013-08-08
  • Jquery 點(diǎn)擊按鈕顯示和隱藏層的代碼

    Jquery 點(diǎn)擊按鈕顯示和隱藏層的代碼

    不好意思,剛剛發(fā)了一個(gè)類(lèi)似的效果,發(fā)現(xiàn)代碼比較多,而卻還有一個(gè)bug,現(xiàn)在修正了錯(cuò)誤,需要的朋友可以參考下。
    2011-07-07
  • 基于jquery tab切換(防止頁(yè)面刷新)

    基于jquery tab切換(防止頁(yè)面刷新)

    tab切換,是一個(gè)很常見(jiàn)的效果,今天在項(xiàng)目中遇到這樣一個(gè)問(wèn)題。就是切換后,頁(yè)面刷新,又重新定位到第一個(gè)上了,很是郁悶
    2012-05-05
  • jquery中的 $("#jb51")與document.getElementById("jb51") 的區(qū)別

    jquery中的 $("#jb51")與document.getElementById("

    以前沒(méi)注意過(guò),認(rèn)為jquery 中的 $("#jb51") 與 document.getElementById("jb51") 是一回事,指的是同一個(gè)東西。
    2011-07-07
  • JQuery之focus函數(shù)使用介紹

    JQuery之focus函數(shù)使用介紹

    focus函數(shù)可以用來(lái)發(fā)生點(diǎn)擊某個(gè)按鈕或者提交值錯(cuò)誤等觸發(fā)事件發(fā)生時(shí)把焦點(diǎn)給到某個(gè)元素,具體用法如下,感興趣的朋友可以參考下
    2013-08-08
  • Jquery插件寫(xiě)法筆記整理

    Jquery插件寫(xiě)法筆記整理

    大部分jQuery插件都是這種類(lèi)型的插件,由于這種插件是將對(duì)象方法封裝起來(lái),在jQuery選擇器獲取jQuery對(duì)象過(guò)程中進(jìn)行操作,從而發(fā)揮jQuery強(qiáng)大的選擇器優(yōu)勢(shì)
    2012-09-09
  • jQuery實(shí)現(xiàn)消息滾動(dòng)播放效果

    jQuery實(shí)現(xiàn)消息滾動(dòng)播放效果

    這篇文章主要為大家詳細(xì)介紹了jQuery實(shí)現(xiàn)消息滾動(dòng)播放效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 即將發(fā)布的jQuery 3 有哪些新特性

    即將發(fā)布的jQuery 3 有哪些新特性

    本文主要介紹jQuery 3中一些新增的特性和一些變更的特性,以及一些廢棄刪除的特性,另外介紹了jQuery 3.0 最大的變化就是徹底放棄對(duì) IE8 的支持,大家可以先看一下。
    2016-04-04
  • 老生常談jquery id選擇器和class選擇器的區(qū)別

    老生常談jquery id選擇器和class選擇器的區(qū)別

    下面小編就為大家?guī)?lái)一篇老生常談jquery id選擇器和class選擇器的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • 淺析JQuery UI Dialog的樣式設(shè)置問(wèn)題

    淺析JQuery UI Dialog的樣式設(shè)置問(wèn)題

    本篇文章主要是對(duì)JQuery中UI Dialog的樣式設(shè)置問(wèn)題進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-12-12

最新評(píng)論