學習 jQuery 基本原理,探索其特性和功能,執行一些常見的 Ajax 任務並掌握如何使用外掛程式擴充 jQuery。
jQuery 是什嗎?
jQuery 由 John Resig 建立於 2006 年初,對於任何使用 JavaScript 代碼的程式員來說,它是一個非常有用的 JavaScript 庫。無論您是剛剛接觸 JavaScript 語言,並且希望獲得一個能解決文件物件模型(Document Object Model,DOM)指令碼和 Ajax 開發中一些複雜問題的庫,還是作為一個厭倦了 DOM 指令碼和 Ajax 開發中無聊的重複工作的資深 JavaScript 專家,jQuery 都會是您的首選。
jQuery 能協助您保證代碼簡潔易讀。您再也不必編寫大堆重複的迴圈代碼和 DOM 指令碼庫調用了。使用 jQuery,您可以把握問題的要點,並使用儘可能最少的代碼實現您想要的功能。
毫無疑問,jQuery 的原理是獨一無二的:它的目的就是保證代碼簡潔並可重用。當您理解並體會這一原理後,便可以開始學習本教程了,看看 jQuery 對我們的編程方式有多少改進吧。
一些簡單的代碼簡化
下面是一個簡單樣本,它說明了 jQuery 對代碼的影響。要執行一些真正簡單和常見的任務,比方說為頁面的某一地區中的每個連結附加一個單擊(click)事件,您可以使用純 JavaScript 代碼和 DOM 指令碼來實現,如 清單 1 所示。
清單 1. 沒有使用 jQuery 的 DOM 指令碼
複製代碼 代碼如下:
var external_links = document.getElementById('external_links');
var links = external_links.getElementsByTagName('a');
for (var i=0;i < links.length;i++) {
var link = links.item(i);
link.onclick = function() {
return confirm('You are going to visit: ' + this.href);
};
}
清單 2 顯示了使用 jQuery 實現的相同的功能。
清單 2. 使用了 jQuery 的 DOM 指令碼
複製代碼 代碼如下:
$('#external_links a').click(function() {
return confirm('You are going to visit: ' + this.href);
});
是不是很神奇? 使用 jQuery,您可以把握問題的要點,只讓代碼實現您想要的功能,而省去了一些繁瑣的過程。無需對元素進行迴圈,click() 函數將完成這些操作。同樣也不需要進行多個 DOM 指令碼調用。您只需要使用一個簡短的字串對所需的元素進行定義即可。
理解這一代碼的工作原理可能會有一點複雜。首先,我們使用了 $() 函數 —— jQuery 中功能最強大的函數。通常,我們都是使用這個函數從文檔中選擇元素。在本例中,一個包含有一些層疊樣式表(Cascading Style Sheet,CSS)文法的字串被傳遞給函數,然後 jQuery 儘可能高效地把這些元素找出來。
如果您具備 CSS 選取器的基本知識,那麼應該很熟悉這些文法。在 清單 2 中,#external_links 用於檢索 id 為 external_links 的元素。a 後的空格表示 jQuery 需要檢索 external_links 元素中的所有 <a> 元素。用英語說起來非常繞口,甚至在 DOM 指令碼中也是這樣,但是在 CSS 中這再簡單不過了
$() 函數返回一個含有所有與 CSS 選取器匹配的元素的 jQuery 對象。jQuery 對象 類似於數組,但是它附帶有大量特殊的 jQuery 函數。比方說,您可以通過調用 click 函數把 click 處理函數指定給 jQuery 對象中的所有元素。
還可以向 $() 函數傳遞一個元素或者一個元素數組,該函數將把這些元素封裝在一個 jQuery 對象中。您可能會想要使用這個功能將 jQuery 函數用於一些對象,比方說 window 對象。例如,我們通常會像下面這樣把函數分配給載入事件:
window.onload = function() {
// do this stuff when the page is done loading
};
使用 jQuery 編寫的功能相同的代碼:
$(window).load(function() {
// run this when the whole page has been downloaded
});
您可能有所體會,等待視窗載入的過程是非常緩慢而且令人痛苦的,這是因為必須等整個頁面載入完所有的內容,包括頁面上所有的的圖片。有的時候,您希望首先完成圖片載入,但是在大多數情況下,您只需載入超文本標誌語言(Hypertext Markup Language,HTML)就可以了。通過在文檔中建立特殊的 ready 事件,jQuery 解決了這個問題,方法如下:
$(document).ready(function() {
// do this stuff when the HTML is all ready
});
這個代碼圍繞 document 元素建立了一個 jQuery 對象,然後建立一個函數,用於在 HTML DOM 文檔就緒的時候調用執行個體。可以根據需要任意地調用這個函數。並且能夠以真正的 jQuery 格式,使用捷徑調用這個函數。這很簡單,只需向 $() 函數傳遞一個函數就可以了:
$(function() {
// run this when the HTML is done downloading
});
到目前以止,我已經向大家介紹了 $() 函數的三種用法。第四種方法可以使用字串來建立元素。結果會產生一個包含該元素的 jQuery 對象。清單 3 顯示的樣本在頁面中添加了一個段落。
清單 3. 建立和附加一個簡單的段落
$('<p></p>')
.html('Hey World!')
.css('background', 'yellow')
.appendTo("body");
在前一個例子中您可能已經注意到,jQuery 中的另一個功能強大的特性就是方法連結(method chaining)。每次對 jQuery 對象調用方法時,方法都會返回相同的 jQuery 對象。這意味著如果您需要對 jQuery 對象調用多個方法,那麼您不必重新鍵入選取器就可以實現這一目的:
$('#message').css('background', 'yellow').html('Hello!').show();
使 Ajax 變得簡單
使用 jQuery 將使 Ajax 變得及其簡單。jQuery 提供有一些函數,可以使簡單的工作變得更加簡單,複雜的工作變得不再複雜。
Ajax 最常見的用法就是把一塊 HTML 程式碼載入到頁面的某個地區中去。為此,只需簡單地選擇所需的元素,然後使用 load() 函數即可。下面是一個用於更新統計資料的樣本:
$('#stats').load('stats.html');
通常,我們只需簡單地把一些參數傳遞給伺服器中的某個頁面。正如您所預料的,使用 jQuery 實現這一操作非常地簡單。您可以使用 $.post() 或者 $.get(),這由所需的方法決定。如果需要的話,您還可以傳遞一個可選的資料對象和回呼函數。清單 4 顯示了一個發送資料和使用回調的簡單樣本。
清單 4. 使用 Ajax 向頁面發送資料
$.post('save.cgi', {
text: 'my string',
number: 23
}, function() {
alert('Your data has been saved.');
});
如果您確實需要編寫一些複雜的 Ajax 指令碼,那麼需要用到 $.ajax() 函數。您可以指定 xml、script、html 或者 json,jQuery 將自動為回呼函數準備合適的結果,這樣您便可以立即使用該結果。還可以指定 beforeSend、error、success 或者 complete 回呼函數,向使用者提供更多有關 Ajax 體驗的反饋。此外,還有一些其它的參數可供使用,您可以使用它們設定 Ajax 請求的逾時,也可以設定頁面 “最近一次修改” 的狀態。清單 5 顯示了一個使用一些我所提到的參數檢索 XML 文檔的樣本。
清單 5. $.ajax() 使 Ajax 由複雜變簡單
$.ajax({
url: 'document.xml',
type: 'GET',
dataType: 'xml',
timeout: 1000,
error: function(){
alert('Error loading XML document');
},
success: function(xml){
// do something with xml
}
});
當 success 回呼函數返回 XML 文檔後,您可以使用 jQuery 檢索這個 XML 文檔,其方式與檢索 HTML 文檔是一樣的。這樣使得處理 XML 文檔變得相當地容易,並且把內容和Data Integration到了您的 Web 網站裡面。清單 6 顯示了 success 函數的一個擴充,它為 XML 中的每個 <item> 元素都添加了一個清單項目到 Web 頁面中。
清單 6. 使用 jQuery 處理 XML 文檔
success: function(xml){
$(xml).find('item').each(function(){
var item_text = $(this).text();
$('<li></li>')
.html(item_text)
.appendTo('ol');
});
}
為 HTML 添加動畫
可以使用 jQuery 處理基本的動畫和顯示效果。animate() 函數是動畫代碼的核心,它用於更改任何隨時間變化的數值型的 CSS 樣式值。比方說,您可以變化高度、寬度、不透明度和位置。還可以指定動畫的速度,定為毫秒或者預定義的速度:慢速,中速或快速。
下面是一個同時變化某個元素高度和寬度的樣本。請注意,這些參數沒有開始值,只有最終值。開始值取自元素的當前尺寸。同時我也附加了一個回呼函數。
$('#grow').animate({ height: 500, width: 500 }, "slow", function(){
alert('The element is done growing!');
});
jQuery 的內建函數使更多常見的動畫更容易完成。可以使用 show() 和 hide() 元素,立即顯示或者以特定的速度顯示。還可以通過使用 fadeIn() 和 fadeOut(),或者 slideDown() 和 slideUp() 顯示和隱藏元素,這取決於您所需要的顯示效果。下面的樣本定義了一個下滑的導覽功能表。
$('#nav').slideDown('slow');
DOM 指令碼和事件處理
或許 jQuery 最擅長的就是簡化 DOM 指令碼和事件處理。遍曆和處理 DOM 非常簡單,同時附加、移除和呼叫事件也十分容易,且不像手動操作那樣容易出錯。
從本質上說,jQuery 可以使 DOM 指令碼中的常用操作變得更加容易。您可以建立元素並且使用 append() 函數把它們與其它的一些元素連結到一起,使用 clone() 複製元素,使用 html() 設定內容,使用 empty() 函數刪除內容,使用 remove() 函數刪除所有的元素,即便是使用 wrap() 函數,用其他元素將這些元素封裝起來。
通過遍曆 DOM,一些函數可以用於更改 jQuery 對象本身的內容。可以獲得元素所有的 siblings()、parents() 和 children()。還可以選擇 next() 和 prev() 兄弟元素。find() 函數或許是功能最強大的函數,它允許使用 jQuery 選取器搜尋 jQuery 對象中元素的後代元素。
如果結合使用 end() 函數,那麼這些函數將變得更加強大。這個函數的功能類似於 undo 函數,用於返回到調用 find() 或 parents() 函數(或者其它遍曆函數)之前的 jQuery 對象。
如果配合方法連結(method chaining)一起使用,這些函數可以使複雜的操作看上去非常簡單。清單 7 顯示了一個樣本,其中包含有一個登入表單並處理了一些與之有關的元素。
清單 7. 輕鬆地遍曆和處理 DOM
$('form#login')
// hide all the labels inside the form with the 'optional' class
.find('label.optional').hide().end()
// add a red border to any password fields in the form
.find('input:password').css('border', '1px solid red').end()
// add a submit handler to the form
.submit(function(){
return confirm('Are you sure you want to submit?');
});
不管您是否相信,這個樣本只是一行滿是空白的被連結的代碼。首先,選擇登入表單。然後,發現其中含有可選標籤,隱藏它們,並調用 end() 返回表單。然後,我建立了密碼欄位,將其邊界變為紅色,再次調用 end() 返回表單。最後,我在表單中添加了一個提交事件處理常式。其中尤為有趣的就是(除了其簡潔性以外),jQuery 完全最佳化了所有的查詢操作,確保將所有內容很好地連結在一起後,不需要對一個元素執行兩次查詢。
處理常見事件就像調用函數(比方說 click()、submit() 或 mouseover())和為其傳遞事件處理函數一樣簡單。此外,還可以使用 bind('eventname', function(){}) 指定自訂的事件處理常式。可以使用 unbind('eventname') 刪除某些事件或者使用 unbind() 刪除所有的事件。有關這些函數的使用方法的完整列表,請參閱 參考資料 中的 jQuery API(Application Program Interface,API)文檔。
釋放 jQuery 選取器的強大能量
我們經常會使用 ID 來選擇元素,比如 #myid,或者通過類名,比如 div.myclass 來選擇元素。然而,jQuery 提供了更為複雜和完整的選取器文法,允許我們在單個選取器中選擇幾乎所有的元素組合。
jQuery 的選取器文法主要是基於 CSS3 和 XPath 的。對 CSS3 和 XPath 瞭解的越多,使用 jQuery 時就越加得心應手。
CSS3 包含一些並不是所有瀏覽器都支援的文法,因此我們很少使用它。然而,我們仍然可以在 jQuery 中使用 CSS3 選擇元素,因為 jQuery 具備自己的自訂選取器引擎。比方說,要在表格中的每一個空列中都添加一個橫杠,可以使用::empty 偽選取器(pseudo-selector):
$('td:empty').html('-');
如果需要找出所有不含特定類的元素呢? CSS3 同樣提供了一個文法可以完成這個目的,使用 :not 偽選取器: 如下代碼顯示了如何隱藏所有不含 required 類的輸入內容:
$('input:not(.required)').hide();
與在 CSS 中一樣,可以使用逗號將多個選取器串連成一個。下面是一個同時隱藏頁面上所有類型列表的簡單樣本:
$('ul, ol, dl').hide();
XPath 是一種功能強大的文法,用於在文檔中搜尋元素。它與 CSS 稍有區別,不過它能實現的功能略多於 CSS。要在所有複選框的父元素中添加一個邊框,可以使用 XPath 的 /.. 文法:
$("input:checkbox/..").css('border', '1px solid #777');
jQuery 中也加入了一些 CSS 和 XPath 中沒有的選取器。比方說,要使一個表更具可讀性,通常可以在表格的奇數行或偶數行中附加一個不同的類名 —— 也可以稱作把表分段(striping)。使用 jQuery 不費吹灰之力就可以做到這點,這需要歸功於 odd 偽選取器。下面這個例子使用 striped 類改變了表格中所有奇數行的背景顏色:
$('table.striped > tr:odd').css('background', '#999999');
我們可以看到強大的 jQuery 選取器是如何簡化代碼的。不論您想處理什麼樣的元素,不管這個元素是具體的還是模糊的,都有可能找到一種方法使用一個 jQuery選取器對它們進行定義。
使用外掛程式擴充 jQuery
與大多數軟體不同,使用一個複雜的 API 為 jQuery 編寫外掛程式並不是非常困難。事實上,jQuery 外掛程式非常易於編寫,您甚至希望編寫一些外掛程式來使代碼更加簡單。下面是可以編寫的最基本的 jQuery 外掛程式:
$.fn.donothing = function(){
return this;
};
雖然非常簡單,但是還是需要對這個外掛程式進行一些解釋。首先,如果要為每一個 jQuery 對象添加一個函數,必須把該函數指派給 $.fn。第二,這個函數必須要返回一個 this(jQuery 對象),這樣才不至於打斷 方法連結(method chaining)。
可以輕鬆地在這個樣本之上構建。要編寫一個更換背景顏色的外掛程式,以替代使用 css('background'),可以使用下面的代碼:
$.fn.background = function(bg){
return this.css('background', bg);
};
清注意,可以只從 css() 傳回值,因為已經返回了 jQuery 對象。因此,方法連結(method chaining)仍然運作良好。
我建議在需要重複工作的時候使用 jQuery 外掛程式。比方說,如果您需要使用 each() 函數反覆執行相同的操作,那麼可以使用一個外掛程式來完成。
由於 jQuery 外掛程式相當易於編寫,所以有上百種可供你選擇使用。jQuery 提供的外掛程式可用於製表、圓角、滑動顯示、工具提示、日期選取器,以及我們可以想到的一切效果。
最為複雜、使用最為廣泛的外掛程式要屬介面(Interface),它是一種動畫外掛程式,用於處理排序、拖放功能、複雜效果、以及其它有趣和複雜的使用者介面(User Interface,UI)。介面對於 jQuery 來說就如 Scriptaculous 對於 Prototype 一樣。
表單外掛程式也同樣流行且非常有用,通過它可以使用 Ajax 在後台中輕鬆地提交表單。這個外掛程式用於處理一些常見的情況:您需要截獲某個表單的提交事件,找出所有不同的輸入欄位,並使用這些欄位構造一個 Ajax 調用。
結束語
只是簡要地介紹了使用 jQuery 可能完成的任務。jQuery 使用起來非常有趣,因此我們總是能學到看上去很簡單的新技巧和新特性。從剛開始使用 jQuery 的那一刻起,jQuery 便可以完全簡化您的 JavaScript 和 Ajax 編程;每學會一點新知識,您的代碼就會更簡單一點。
學習了 jQuery 之後,我在使用 JavaScript 語言進行編程的同時也獲得了許多的樂趣。不用操心所有無聊的內容,我可以專註地編寫有趣的內容。使用 jQuery 後,我幾乎就告別了編寫 for 迴圈代碼的時代。甚至在想到要使用其它 JavaScript 庫時,不禁會有所畏縮不前。jQuery 確確實實改變了我對 JavaScript 編程的看法。