關鍵字:   jQuery    

這份指南是對jQeury庫的介紹,它需要對JavaScript和文檔對象模型(DOM)有基本的了解。它從零開始講解并解釋必要的細節。
該指南講到了一個簡單的hello world例子,selector和event基礎,AJAX,FX以及使用和創作plugins。
這份指南不包含"click me"例子,只提供"copy me"代碼的意圖是激發你來自己嘗試例子。Copy一個例子,看看它做什么,并修改它。

目錄
1 Setup
2 Hello jQuery
3 Find me: 使用selectors和events
4 Rate me: 使用Ajax
5 Animate me: 使用Effects
6 Sort me: 使用tablesorter plugin
7 Plug me: 寫你自己的plugins
8 Next steps

Setup
我們首先需要jQuery庫的copy來開始。最新的版本可以在http://docs.jquery.com/Downloading_jQuery找到,這份指南也提供一個基本包來下載。
jQuery Starterkit
下載該文件并解壓,用你最喜歡的編輯器打開starterkit.html和custom.js并用瀏覽器打開starterkit.html。
現在我們準備好了開始著名的"Hello world"例子的任何事情。
本節里有意思的鏈接:
jQuery Starterkit
Downloading jQuery

Hello jQuery
當我們使用jQuery時所做的幾乎任何事情都會讀取或操作文檔對象模型(DOM),我們需要確認一旦DOM準備好了則我們開始添加events等東西。
為了做這件事,我們為document注冊一個ready事件。

代碼
  1. $(document).ready(function() {  
  2.     // do stuff when DOM is ready  
  3. });  

在該方法里放入一個alert不會有多大意義,因為alert不需要DOM成功loaded。所以讓我們嘗試一些更復雜的東西:當點擊該鏈接時顯示一個alert。
代碼
  1. $(document).ready(function() {  
  2.     $("a").click(function() {  
  3.         alert("Hello world!");  
  4.     });  
  5. });  

這將在你點擊該鏈接時顯示alert。
讓我們看看我們做了什么:$("a")是一個jQuery selector,在這里,它選擇所有的a元素。$本身為jQuery"類"的別名,因此$()構建了一個jQuery對象。
我們下一步調用的click()方法為該jQuery對象的一個方法。它綁定了一個click事件到所有被選擇的元素(在這里為一個單獨的anchor元素)并當事件發生時執行
提供的方法。
這與下面的代碼類似:
代碼
  1. <a href="" onclick="alert('Hello world')">Link</a>  

區別非常明顯:我們不需要為每個單獨的元素寫一個onclick。對結構(HTML)和行為(JS)我們有一個清晰的分離,就像我們使用CSS來分離結構和呈現。
了解了這些,我們來對selectors和events做一些更多的東西。
本節里有意思的鏈接:
jQuery Base
jQuery Expressions
jQuery Basic Events

Find me: 使用selectors和events
jQuery提供了兩種方式來選擇元素。第一種使用作為字符串傳遞給jQuery構造器的CSS和XPath選擇器的聯合(例如$("div > ul a"))。第二種使用jQuery對象的
一些方法。兩種方式可以聯合。
我們選擇并修改我們的starterkit里的第一個排序列表來嘗試一些選擇器。
我們以選擇列表本身開始。列表有一個ID "orderedlist"。在傳統的JavaScript里,你可以通過使用document.getElementById("orderedlist")來使用它。使用
jQuery的話,我們像這樣做:

代碼
  1. $(document).ready(function() {  
  2.     $("#orderedlist").addClass("red");  
  3. });  

starterkit提供了一個帶有一個class為"red"的簡單的添加一個紅色背景的stylesheet。因此,當你在瀏覽器里reload頁面時,你應該看到第一個ordered list
將擁有一個紅色背景。第二個list則沒變。
現在讓我們添加一些classes到該list的子元素中。
代碼
  1. $(document).ready(function() {  
  2.     $("#orderedlist > li").addClass("blue");  
  3. });  

這將選擇id為orderedlist的元素的所有子li元素并為其添加class "blue"。
現在看看一個更復雜的:我們希望當用戶hover到該list的最后一個li元素時添加和刪除class。
代碼
  1. $(document).ready(function() {  
  2.     $("#orderedlist li:last").hover(function() {  
  3.         $(this).addClass("green");  
  4.     },function() {  
  5.         $(this).removeClass("green");  
  6.     });  
  7. });  

有許多其他類似于CSSXPath語法的選擇器。更多的例子以及一個所有可得到的表達式的列表可以在這里找到。
對每個可得到的onxxx事件,像onclick,conchange,onsubmit,都有一個jQuery等價物。一些其他的事件,像ready和hover,被提供來作為方法方便某些任務。
你可以在jQuery Events Documentation里找到完整的事件列表。
使用這些selectors和events你已經可以做許多事情,但是這里還有一個。
代碼
  1. $(document).ready(function() {  
  2.     $("#orderedlist").find("li").each(function(i) {  
  3.         $(this).append(" BAM! " + i);  
  4.     });  
  5. });  

find()允許你對已經選擇的元素做更深的子搜索,因此$("#orderedlist").find("li")幾乎和$("#orderedlist li")一樣。
each()對每個元素迭代并允許更多的處理。大多數方法,像addClass(),自己使用each()。
在這個例子中,append()用來在每個元素的末尾添加一些文本。
另外一個你經常面對的任務是在jQuery沒有cover的DOM元素上調用方法。考慮一個你想在通過AJAX成功提交后reset它的form。
代碼
  1. $(document).ready(function() {  
  2.     // use this to reset a single form  
  3.     $("#reset").click(function() {  
  4.         $("#form").reset();  
  5.     });  
  6. });  

這些代碼選擇ID為"form"的元素并對每個選擇的元素調用reset()。當你有多于一個form時,你也可以這樣做:
代碼
  1. $(document).ready(function() {  
  2.     // use this to reset several forms at once  
  3.     $("#reset").click(function() {  
  4.         $("form").reset();  
  5.     });  
  6. });  

這將在你的document里選擇所有的forms,迭代它們并對每個調用reset()。
另一個你可能面臨的問題是不選擇某一個元素。jQuery為它提供filter()和not()。filter()通過滿足該filter表達式來減少選擇的元素,not()則相反刪除掉
所有滿足該表達式的元素。考慮一個unordered的list,你想選擇所有沒有ul子元素的li元素。
代碼
  1. $(document).ready(function() {  
  2.     $("li").not("[ul]").css("border", "1px solid black");  
  3. });  

這將選擇所有的li元素并刪除有ul子元素的元素。因此所有的li元素將有一個border,除了有ul子元素的。[expression]語法來自XPath并且可以用來被子元素
和屬性filter。可能你想選擇所有的有一個name屬性的anchors:
代碼
  1. $(document).ready(function() {  
  2.     $("a[@name]").background("#eee");  
  3. });  

這將對所有的有一個name屬性的anchor元素添加一個background顏色。
比通過name選擇anchors更常用的是,你可能需要通過它們的"href"屬性選擇anchors。由于瀏覽器的行為不一致這可能返回不同的"href"值(注意:這個問題最近
在jQuery中解決了,只要在1.1.1版本后都可以)。為了只匹配一部分值,我們可以使用包含選擇"*="來代替等于"=":
代碼
  1. $(document).ready(function() {  
  2.     $("a[@href*=/content/gallery]").click(function() {  
  3.         // do something with all links that point somewhere to /content/gallery  
  4.     });  
  5. });  

到目前為止,所有的selectors用來選擇子或filter當前選擇。還有你需要選擇前一個或下一個元素的情況,即所謂的siblings。考慮FAQ頁面,所有的答案首先
隱藏,而當問題點擊時顯示。該jQuery代碼為:
代碼
  1. $(document).ready(function() {  
  2.     $('#faq').find('dd').hide().end().find('dt').click(function() {  
  3.         $(this).next().slideToggle();  
  4.     });  
  5. });  

這里我們使用鏈來減少代碼量并得到更好的性能,因為'#faq'只選擇了一次。
通過使用end(),第一個find()不會結束,則我們可以對#faq元素繼續搜索下一個find(),而不是對dd子元素操作。
在click處理器即傳遞給click()方法的function里,我們使用$(this).next()來從當前dt查找下一個sibling。這允許我們快速選擇緊跟在點擊的問題后的答案。
除了sibling,你也可以選擇父元素(對屬性XPath的人而言為所謂的ancestors)。你可能想對用戶hover的鏈接的父paragraph高亮,試試這個:
代碼
  1. $(document).ready(function() {  
  2.     $("a").hover(function() {  
  3.         $(this).parents("p").addClass("highlight");  
  4.     },function() {  
  5.         $(this).parents("p").removeClass("highlight");  
  6.     });  
  7. });  

對于所有hover的anchor元素,搜索它的父paragraph并添加和刪除一個"highlight" class。
讓我們繼續之前了解一下:jQuery很多時候是讓代碼變得更短而更容易閱讀和維護。以下是一個$(document).ready(callback)記號的捷徑:
代碼
  1. $(function() {  
  2.     // code to execute when the DOM is ready  
  3. });  

對于Hello world!例子,我們可以這樣寫:
代碼
  1. $(function() {  
  2.     $("a").click(function() {  
  3.         alert("Hello world!");  
  4.     });  
  5. });  

現在有了基本知識后,我們想explore一些其它方面,開始使用AJAX。
本節里有意思的鏈接:
jQuery API documentation
Visual jQuery - A catgorized browsable API documentation.
jQuery Selectors
jQuery Events
jQuery DOM Traversing

Rate me: 使用Ajax
在這個部分我們寫一個小Ajax程序,它允許用戶rate something,就像在youtube.com上做的一樣。
我們需要一些服務器端代碼來完成這個。我的例子使用php文件來讀"rating"參數并返回ratings的數量和平均的rating。看看rate.php的服務器端代碼。
我們想讓這個例子用Ajax來工作,因此我們用jQuery生成一些必要的東西并加到一個ID為"rating"的容器里

代碼
  1. $(document).ready(function() {  
  2.     // generate markup  
  3.     $("#rating").append("Please rate: ");  
  4.   
  5.     for ( var i = 1; i <=5; i++ )  
  6.         $("#rating").append("<a href='#'>" + i + "</a>");  
  7.   
  8.     // add markup to container and applier click handlers to anchors  
  9.     $("$raing a ").click(function(e)   
  10.         // send request  
  11.         $.post("rate.php", {rating: $(this).html()}, function(xml) {  
  12.             // format and output result  
  13.             $("#rating").html(  
  14.                 "Thanks for rating, current average: " +   
  15.                 $("average", xml).text() +  
  16.                 ", number of votes: " +  
  17.                 $("count", xml).text()  
  18.             );  
  19.         });  
  20.   
  21.         // stop normal link click  
  22.         return false;  
  23.     });  
  24. });  

這個代碼片段生成5個anchor元素并把它們添加到id為"rating"的容器元素。最后,對容器里的每個anchor添加一個click處理器。當點擊anchor時,一個以anchor
的內容為參數的post請求發送到rate.php。結果作為一個XML返回,并添加到容器代替anchors。
如果你手頭上沒有一個安裝的PHP服務器,你可以看看一個online example。對于一個非常好的甚至不用JavaScript工作的rating系統的例子,訪問softonic.de
點擊"Kurz bewerten!"
jQuery的Ajax方法的更多的文檔可以在Ajax Documentation或者用Ajax開發的Visual jQuery上找到。
當通過Ajax載入內容時遇到的一個非常常見的問題是:當添加事件處理器到你的文檔時,如果事件處理器也適合載入的內容,則你必須在內容載入之后也添加這些
處理器。為了防止代碼重復,你可以寫一個方法代理。例如:
代碼
  1. function addClickHandlers() {  
  2.     $("a.remote", this).click(function() {  
  3.         $("#target").load(this.href, addClickHandlers);  
  4.     });  
  5. }  
  6. $(document).ready(addClickHandlers);  

現在一旦當DOM為ready以及每次當一個用戶點擊class為remote的鏈接并且內容完成載入后addClickHandlers都會被調用。
注意$("a.remote", this)查詢,this傳遞過來作為一個context:對于document ready事件,this表示document,則它搜索整個document中class為remote的anchors
當addClickHandlers用來作為load()的回調時,this表示另一個不同的元素:在這個例子中,表示id為target的元素。這防止了click事件一次又一次的賦給同一
鏈接,從而最終導致崩潰。
回調的另一個常見的問題是參數。你已經指定了你的回調但是需要傳遞一個額外的參數。達到次目標的最簡單的方式是在另一個方法里包裝回調:
代碼
  1. // get some data  
  2. var foobar = ...;  
  3.   
  4. // specify handler, it needs data as a parameter  
  5. function handler(data) {  
  6.     // ...  
  7. }  
  8.   
  9. // add click handler and pass foobar!  
  10. $('a').click(function() {  
  11.     handler(foobar);  
  12. });  
  13.   
  14. // if you need the context of the original handler, use apply:  
  15. $('a').click(function() {  
  16.     handler.apply(this, [foobar]);  
  17. });  

使用Ajax我們可以cover許多"Web 2.0"。既然我們已經看了一些基本的Ajax,讓我們添加一些簡單的effects和animations到頁面中。
本節有意思的鏈接:
jQuery Ajax Documentation
jQuery API - 包含所有的jQuery方法的描述和例子
Thick Box - 一個使用jQuery來加強著名的lightbox的jQuery插件

Animate me: 使用Effects
可以使用jQuery的show()和hide()構建的簡單的animations。

代碼
  1. $(document).ready(function() {  
  2.     $("a").toggle(function() {  
  3.         $(".stuff").hide('slow');  
  4.     },function() {  
  5.         $(".stuff").show('fast');  
  6.     });  
  7. });  

你可以使用animate()創建任何animations的聯合。例如,一個具有fade的slide:
代碼
  1. $(document).ready(function() {  
  2.     $("a").toggle(function() {  
  3.         $(".stuff").animate({ height: 'hide', opacity: 'hide' }, 'slow');  
  4.     },function() {  
  5.         $(".stuff").animate({ height: 'show', opacity: 'show' }, 'slow');  
  6.     });  
  7. });  

更炫的effects可以在interface plugin collection找到。該站點提供demos和文檔。雖然Interface在jQuery的插件列表的最前面,還有許多其他的插件。下一
部分顯示了怎樣使用tablesorter插件。
本節有意思的鏈接:
jQuery Effects Documentation
Interface plugin

Sort me: 使用tablesorter plugin
tablesorter插件允許在客戶端對表格排序。你只需引入jQuery和插件,并告訴插件哪個表格是你想排序的。
添加以下內容到starterkit.html(下jquery引入的下面)來嘗試該例子:

代碼
  1. <script src="lib/jquery.tablesorterjs"></script>  

引入了該插件后,你可以像這樣調用它:
代碼
  1. $(document).ready(function() {  
  2.     $("#large").tableSorter();  
  3. });  

試著點擊table的頭部并看看它怎樣在第一次升序排序以及第二次降序排序。該表格可以使用一些行高亮,我們可以通過傳遞一些選項來添加這個:
代碼
  1. $(document).ready(function() {  
  2.     $("#large").tableSorter({  
  3.         // Class names for striping supplied as a array.  
  4.         stripingRowClass: ['odd', 'even'],  
  5.         // Stripe rows on tableSorter init  
  6.         stripeRowsOnStartUp: true  
  7.     });  
  8. });  

tablesorter homepage有更多關于可得到的選項的例子和文檔。
大多數插件可以像這樣使用:引入插件文件并在某些元素上調用插件方法,傳遞一些選項設置來定制插件。
一個可得到的up-to-date插件列表可以在jQuery Plugin site找到。
當你使用jQuery的越頻繁,你可能發現把你自己的代碼打包成一個插件非常有用,可以為你自己或者你的公司重用它,或者與社區分享。下一節講述了怎樣構建
一個插件。
本節有意思的鏈接:
Plugins for jQuery
Tablesorter Plugin

Plug me: 寫你自己的plugins
為jQuery寫你自己的插件非常簡單。如果你遵循下面的規則,則其他人集成你的插件也非常簡單。
插件命名
為你的插件找一個名字,讓我們稱我們的例子為"foobar"。創建一個名為jquery.[yourpluginname].js文件,例如,jquery.foobar.js。
添加一個自定義方法
通過擴展jQuery對象來創建一個或多個插件方法,例如:

代碼
  1. jQuery.fn.foobar = function() {  
  2.     // do something  
  3. };  

則通過執行下面代碼就可以得到使用上面的插件:
代碼
  1. $(...).foobar();  

默認設置:
創建可以被用戶更改的默認設置,例如:
代碼
  1. jQuery.fn.foobar = function(options) {  
  2.     var settings = jQuery.extend({  
  3.         value: 5, name: "pete", bar: 655  
  4.     }, options);  
  5. };  

你可以調用該插件而不帶選項,即使用默認配置:
代碼
  1. $("...").foobar();  

或者帶一些選項:
代碼
  1. $("...").foobar({ value: 123, bar: 9 });  

文檔
如果你發表你的插件,你應該也提供一些例子和文檔。有許多插件可以作為很好的參考。
現在你應該具有了寫插件的基本知識。讓我們來寫一個我們自己的插件。
Checkbox插件
很多人使用jQuery來處理表單時會問到radio buttons或checkboxes的checking和unchecking。他們常用這樣的代碼:
代碼
  1. $("input[@type='checkbox']").each(function() {  
  2.     this.checked = true;  
  3.     this.checked = false; // or, to uncheck  
  4.     this.checked = !this.checked; // or, to toggle  
  5. });  

無論何時你的代碼里有一個each時,你可能想重寫它為一個插件,非常直接:
代碼
  1. jQuery.fn.check = function() {  
  2.     return this.each(function() {  
  3.         this.checked = true;  
  4.     });  
  5. };  

現在該插件可以使用了:
代碼
  1. $("input[@type='checkbox']").check();  

現在你也可以為uncheck()和toggleCheck()寫插件了。但是我們通過擴展我們的插件來接收一些選項來替代。
代碼
  1. jQuery.fn.check = function(mode) {  
  2.     // if mode is undefined, use 'on' as default  
  3.     var mode = mode || 'on';  
  4.   
  5.     return this.each(function() {  
  6.         switch(mode) {  
  7.             case 'on':  
  8.                 this.checked = true;  
  9.                 break;  
  10.             case 'off':  
  11.                 this.checked = false;  
  12.                 break;  
  13.             case 'toggle':  
  14.                 this.checked = !this.checked;  
  15.                 break;  
  16.         }  
  17.     });  
  18. };  

我們可以提供選項"on","off"和"toggle"或者默認無選項,例如:
代碼
  1. $("input[@type='checkbox']").check();  
  2. $("input[@type='checkbox']").check('on');  
  3. $("input[@type='checkbox']").check('off');  
  4. $("input[@type='checkbox']").check('toggle');  

可選設置
寫多于一個設置選項會變得復雜,因為如果用戶想省略第一個參數而只使用第二個參數時他必須傳遞一個null值。
上一節中對tablesorter的使用證明了使用一個對象來解決這個問題。用戶可以省略所有的參數或者為每個他想override的設置傳遞一個具有鍵/值對的對象。
出于練習,你可以嘗試重寫第4節的Voting代碼為一個插件。插件骨架可能看起來像這樣:
代碼
  1. jQuery.fn.rateMe = function(options) {  
  2.     // instead of slecting a static container with  
  3.     // $("#rating"), we now use the jQuery context  
  4.     var container = this;  
  5.   
  6.     var settings = jQuery.extend({  
  7.         url: "rate.php"  
  8.         // put more defaults here  
  9.     }, options);  
  10.   
  11.     // ... rest of the code ...  
  12.   
  13.     // if possible, return "this" to not break the chain  
  14.     return this;  
  15. });  

則可以允許你像這樣允許該插件:
代碼
  1. $(...).rateMe({ url: "test.php" });  

Next steps
如果你計劃開發更多的JavaScript,你應該考慮稱為FireBug的Firefox插件。它提供一個console(很好的替代alerts),一個debugger和其他有用的stuff來為
JavaScript開發。
如果你有不能解決的問題、想分享的主意或者只是需要用jQuery表達你的看法,請自由舒暢的post給jQuery mailing list
對于與本指南相關的任何東西請在我的blog上post一個comment或者直接聯系我。
Whats left...Thanks a lot to John Resig for this greate library! Thanks to the jQuery community for providing John with enough coffee
and everything else!