jQuery 實驗教程:jQuery 簡介、語法及事件處理
jQuery 簡介:為什么使用 jQuery 用
jQuery 是一個跨瀏覽器的免費開源 JavaScript 庫。其核心設計思想是“寫更少的代碼,做更多的事情”(Write Less Do More)。jQuery 提供了一套易于使用的 API。這些 API 極大地簡化了客戶端(瀏覽器)編程過程中的許多方面,包括:
- HTML DOM 的遍歷與操作
- 瀏覽器事件處理
- AJAX(Asynchronous JavaScript And XML)編程
- 特效(如動畫效果)
在直接使用 JavaScropt+DHTML 的傳統客戶端編程方式下,開發人員不得不編寫冗長的代碼。并且,為了使這些代碼能夠兼容不同的瀏覽器,我們還得編寫額外的代碼來處理這些跨瀏覽器問題。 jQuery 的設計目標正是在于簡化客戶端編程。讓我們能夠編寫簡練的代碼,節約開發時間,而這些代碼卻一樣可以功能強大,并且兼容多種瀏覽器。
獲取 jQuery:開始使用 jQuery
jQuery 網站上提供了兩種方式的發布文件。一種是內容經過壓縮的文件;另一種是原始文件。前者文件中不包含代碼注釋以及代碼運行過程中不需要的空白字符,它適合于 生產環境(正式使用的環境)中使用,可以減少文件加載所需時間。后者文件中包含詳細的代碼注釋,適合于開發和測試環境中使用。
jQuery 的下載地址:http://jquery.com/download/
下載 jQuery 之后,在相應的網頁中通過 script 元素引用 jQuery 代碼即可使用它。如清單 1 所示:
清單 1. 從本地站點引用 jQuery
< html > < head > < title >使用 jQuery
|
我們還可以通過 Google、Microsoft 等公司提供的 CDN 服務直接獲取 jQuery。其方法是在需要使用 jQuery 的網頁中直接引用 CDN 服務的 URL。比如,使用 Google 的 CDN 的一個網頁清單 2 所示:
清單 2. 從 CDN 引用 jQuery
< html > < head > < title >使用 jQuery
|
Microsoft 提供的 CDN 的 URL 為: http://ajax.aspnetcdn.com/ajax/jQuery/jQuery-1.9.1.js
Hello World:jQuery 第一個實例
下面的例子中,我們使用 jQuery 實現在頁面上顯示當前時間的功能。
清單 3. Hello World
< html > < head > < meta http-equiv = "content-type" content = "text/html;charset=utf-8" > < script src = "../js/lib/jQuery/1.9.1/jQuery.js" >
|
從上面例子(在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=HelloWorld.htm)
的代碼中我們可以看到, initPage 這個函數會在頁面加載完畢后被調用。而該函數在執行后會在 ID 為 message 的 HTML 結點內添加表示客戶端當前時間的字符串。您可以不必急著去理解上面代碼的具體意思。下一節將介紹 jQuery 的語法。另外,這個例子中我們使用 body 元素的 onload 屬性來綁定事件處理器(initPage)只是為了方便討論。在本章的后面內容中會介紹 jQuery 中用于處理頁面 load 事件綁定的簡便 API。
jQuery 語法:溫故而知新
雖然 jQuery 本身并非一門新的語言。但是,學習其語法有助于我們熟練、靈活地使用它。回顧下我們熟悉的 CSS 語法,不難發現 jQuery 的語法與 CSS 有相似之處。
jQuery 語法的設計思想是”選擇元素,對其操作”。這和 CSS 規則的語法非常類似。比如,要將頁面中一個 ID 為 message 的元素的字體顏色設置為藍色、字體大小設置為 17px,則可以定義如清單 4 所示 CSS 規則:
清單 4. CSS 規則例子
#message{ color:blue; font-size:17px; } |
從上述 CSS 規則中可見,我們期望的對元素外觀的操作(字體顏色設置為藍色、字體大小設置為 17px)是通過” color:blue”和”font-size:17px”這 2 個屬性聲明指定的。而這些操作要作用于哪些元素,則是通過 CSS 的選擇器”#message”指定為 ID 等于“message”的元素。
總結來說,CSS 規則中屬性聲明描述了外觀屬性操作,而選擇器則指定了將相應的屬性操作應用于哪些元素。如圖 1 所示:
jQuery 的語法其實正是模仿了 CSS 規則的語法。其語法如下:
$(selector).action(actionParameter); |
這是個鏈式語法。因此,上述的語法等效于:
var objTargetElements; //要施加操作的目標元素 objTargetElements=$(selector); //指定目標元素 //調用 objTargetElements 的相關方法,對目標元素進行操作 objTargetElements.action(actionParameter); |
上述語法中,
$ :美元符是 jQuery 核心函數 jQuery 的一個別名。當然,在 JavaScript 中“$”是一個合法的函數名。 Selector 參數指定了一個 jQuery 選擇器。jQuery 選擇器類似于 CSS 中的選擇器,它告訴 jQuery 我們準備對哪些元素進行操作(action)。并且,CSS 中的各種選擇器 jQuery 中都有等同的選擇器。
action :該方法指定了要對 selector 所指定的元素進行什么具體操作。actionParameter 參數是個可選參數,是根據具體所指定的方法來定的,它會隨具體方法的變化而變化。
因此,清單 3 中的 jQuery 語句相當于:
清單 5.Query 非鏈式語法示例
/* $("#message").html("Hello World, it is now:" +new Date().toLocaleString()); 相當于: */ var objTargetElements; //要施加操作的目標元素 //指定目標元素為 ID 等于 message 的元素,使用基于 ID 的選擇器 objTargetElements=$( "#message" ); //調用 objTargetElements 的 html 方法,設置目標元素的 HTML 內容 objTargetElements.html ( "Hello World, it is now:" + new Date().toLocaleString()); |
$ 函數的返回值是一個 jQuery 自定義的類似數組的對象。該對象的各個數字下標表示的屬性對應的值為選擇器所匹配的各個元素。
比如,清單 3 中的 $ 函數調用,它為 $ 函數指定了一個基于元素 ID 的選擇器表達式:
$( "#message" ) |
其返回值將滿足下列條件表達式。因為選擇器表達式”#message”匹配了唯一一個 ID 為 message 的元素:
document.getElementById( "message" )==$( "#message" )[0] |
$ 函數返回的對象還提供了一些方法,通過調用該對象的相關方法可以對選擇器所匹配的元素進行相應的操作。比如,清單 3 所示代碼中,我們通過調用$函數返回對象的 html 方法設置選擇器表達式”#message”所匹配的元素的 HTML 內容。
為了更加直觀得了解 $ 函數的返回值,建議您通過 Chrome 瀏覽器中的開發者工具的表達式監視功能( Watch Expressions),觀察一個具體的$函數調用的返回值。如圖 2 所示:
jQuery 的語法和清單 3 中的 jQuery 語句的對應關系如圖 3 所示:
$ 函數返回的對象提供了一個名為 each 的常用方法。 each 方法接受一個參數,該參數是一個回調函數。 each 方法會針對選擇器表達式所匹配的元素中的每個元素逐次調用這個回調函數,并將單個元素及其對應的索引號作為參數傳入該函數。下面看一個實例。
假設在頁面中有多個鏈接,現在要將這個頁面中所有鏈接的 URL 顯示在瀏覽器的控制臺中。
頁面代碼如下所示:
清單 6.$ 函數返回值實例
< a href = "https://www.ibm.com/developerworks/cn/" target = "_blank" > IBM developerWorks 中文站
|
(在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=$FuncReturn.htm)
此時,可以用基于元素名稱的選擇器來匹配多個元素(頁面中所有的鏈接元素),并調用$函數返回值的 each 方法。這里,我們定義一個回調函數( 這個回調函數通常是一個匿名函數,方便代碼編寫),把它作為 each 函數的參數。在這個回調函數中,我們往瀏覽器控制臺中打印每個鏈接的 URL,如清單 7 代碼所示:
清單 7.jQuery 的 each 方法---遍歷集合型對象的簡便方法
//用基于元素名稱的選擇器去匹配頁面中的所有鏈接元素 $( "a" ).each( function (index,ele){ //匿名函數作為 each 方法的參數,供其調用 console.log( "鏈接" +index+ ":" +ele.href); //往控制臺中打印鏈接 URL }); |
現在,您不妨做一個練習,來改變 ID 為 tip 的元素使其能夠以粗體顯示。我們知道,要讓一個元素粗體顯示,只要指定其 CSS 屬性 font-weight 為 bold 即可。也就是說,實現這樣一個功能,我們需要的選擇器是“#tip”,對應的操作是修改 CSS 屬性。因此,jQuery 的代碼是:
$( "#tip" ).css( "font-weight" , "bold" ); |
您可以使用本教程配套的在線代碼編輯器直接編寫代碼練習上面的代碼:
http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=HelloWorld.htm
在線代碼編輯器效果如下圖所示:
jQuery 選擇器:jQuery 利器
了解 jQuery 的語法后,我們明白選擇器是 jQuery 中的核心概念。下面介紹 jQuery 幾種常見的選擇器。這些選擇器我們大都可以從 CSS 中找到它們的影子。
前文講到 Chrome 瀏覽器中的開發者工具表達式監視功能可以讓我們直觀地看到$函數返回值的各個屬性和方法。因此,在我們學習 jQuery 甚至實際工作過程中都可以通過 Chrome 瀏覽器的表達式監控工具直接觀察指定的選擇器表達式所匹配的元素,以便實時地確定所要使用的選擇器表達式是否正確。
基于元素 ID 的選擇器
這種選擇器可以指定唯一的一個元素。清單 3 的代碼就是使用這種選擇器。其語法是:
“#元素 ID”
如果要對一個特定的元素進行操作,那么就可以設置該元素的 ID 屬性值,然后使用基于 ID 的選擇器指定要進行操作的元素。比如,如下 HTML 片段中的 ID 為 btnTest 的元素,就可以用基于元素 ID 的選擇器”#btnTest”來指定。
< input type = "button" id = "btnTest" value = "Test" >
|
如圖 5 所示:
(在線例子http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=IDSelector.htm)
基于元素標簽名的選擇器
如果要對標簽名相同的元素(如都是用標簽”A”表示的超鏈接元素)進行操作,則可以使用基于標簽名的選擇器。其語法如下:
“元素名”
在 CSS 中,我們可以用元素標簽名做選擇器。比如,下面的 CSS 規則表示將所有鏈接的字體尺寸設置為 25 像素。
a{ font-size : 25px ; } |
通過 jQuery 代碼實現上述 CSS 規則的功能,我們可以使用元素標簽名作為選擇器。代碼如清單 8 所示:
清單 8.使用元素標簽名作為選擇器
$( "a" ).each( function (){ //選擇器表達式是"a" $( this ).css( "fontSize" , "25px" ); }); |
在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=EleNameSelector.htm
基于 CSS 類名選擇器
jQuery 也支持 CSS 所支持的類名選擇器。其語法是:
“.類名”
假設我們要把頁面中所有表示金額的輸入框的值都在其前面加一個貨幣符號前綴。這樣的功能實現的時候就可以用基于類名的選擇器了:在頁面中將所有表示金額的輸入框元素的 class 屬性值設為”amount”。再通過如下代碼實現添加貨幣符號的功能。
清單 9.使用 CSS 類名作為選擇器
/* 選擇所有類為 amount 的元素 each 方法會針對選擇器所匹配的每個元素 調用該方法的參數中所指定的函數。并將該 元素作為函數調用的第二個實際參數。 */ $( ".amount" ).each( function (i,ele){ //設置元素的值為其當前值加上貨幣符號前綴 $(ele).val( '¥' +$(ele).val()); }); |
在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=ClsNameSelector.htm
基于元素屬性的選擇器
jQuery 也支持基于元素屬性的選擇器。其語法是:
“元素名[屬性名=屬性指]”
比如下面的 CSS 規則描述了將所有的文本框的背景色設為黃色。
input[type= "text" ]{ background-color :yellow; } |
如上面的頁面效果用 jQuery 代碼實現,則可以使用屬性選擇器來編寫相應的代碼:
清單 10.使用元素屬性作為選擇器
$( "input[type=text]" ).css( 'background-color' , 'yellow' ); |
在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=AttrSelctor.htm
基于 DOM 對象的選擇器
jQuery 也支持使用 DOM 對象作為選擇器。這種選擇器在一些特定情況下會顯得非常有用和方便。
比如清單 3 所示的例子中,監聽頁面加載(load)事件的監聽器 initPage 是通過 body 元素的 onload 屬性來指定的。jQuery 提供了一種簡便的方法來處理頁面的 load 事件綁定。其方法就是使用 document 對象作為選擇器傳遞給$函數。然后調用給函數返回值的 ready 方法。調用時將事件監聽器函數作為 ready 方法的參數傳入。因此,清單 3 所示例子中的頁面 load 事件綁定可以用 jQuery 代碼的方式實現,如下代碼所示:
清單 11.使用 ready 方法處理頁面 load 事件
$(document).ready(initPage); //頁面加載完畢后,jQuery 會回調 initPage |
頁面 load 事件的綁定也可以直接將事件監聽器函數作為 $ 函數的參數直接對該函數進行調用。此時,$ 函數會在頁面加載完畢(即 HTML 文檔及相關資源文件,如 CSS、圖片和 JavaScript 文件,加載完畢后觸發)后,回調這個事件監聽器。因此,上述代碼也可以寫作:
清單 12.直接將函數傳遞給$函數處理頁面 load 事件
$(initPage); |
通常,這樣的事件監聽器可以寫成匿名函數。如下代碼所示:
清單 13.使用匿名函數
$( function (){ //該函數在頁面加載完畢會被 jQuery 調用 //事件處理代碼 }); |
其它選擇器
jQuery 還支持其它類型的選擇器,如基于偽類的選擇器、基于元素層次關系的選擇器等。有關選擇器的進一步信息,您可以參考 jQuery 的 API 文檔:http://api.juery.com/category/selectors。
jQuery 的架構:支持插件機制
jQuery 支持提供插件的方式擴展其功能。從這個角度來將,當我們提到 jQuery 時,默認就是指 jQuery 內核(Core),它是由 jQuery 官方組織所開發和維護的。而使用者則可以根據需要開發一些插件。本教程后面會介紹一些常用 jQuery UI 插件,以及如何自定義一個插件。
jQuery 事件:輕松實現跨瀏覽器的事件處理
bind 方法可以實現事件監聽器的綁定。下面看一個具體的例子。這個例子實現這樣一個功能:
按鈕被單擊后,其下方會顯示或者隱藏一段文本。
清單 14.使用 bind 方法綁定事件監聽器
//當 ID 為 btnDetails 的按鈕被單擊時,下面的匿名函數會被 jQuery 調用 $( "#btnDetails" ).bind( "click" , function (){ $( "#divDetails" ).toggle(); //顯示或者隱藏 ID 為 divDetails 的元素 }); |
從上述的例子(在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=EvtBinding.htm)中可以看出。當選擇器所匹配的元素被單擊時, bind 方法的第二個參數所指定的函數會被 jQuery 調用。而負責顯示/隱藏 divDetails
塊的代碼就會隨著其所在的函數被調用而被執行,從而實現了預期的頁面效果。
bind 方法的語法是:
event :要處理的事件的名稱。該名稱不需要加前綴 on。
handler :事件監聽器,即對瀏覽器事件進行處理的函數。這通常是一個匿名函數。在 event 參數所表示的事件被觸發后,jQuery 會調用這個函數(即回調),并向該函數傳入一個 jQuery 自定義的事件對象。該事件對象是 jQuery 根據原始的瀏覽器事件對象創建的。jQuery 這么做是通過一個”中立”的事件對象來規避不同的瀏覽器所提供的同一個事件的事件對象的屬性不同的問題。這使得我們可以用同樣的代碼處理事件,而不必關心 不同瀏覽器所提供的原始事件對象的差異。
data :表示需要在事件觸發后傳遞給事件監聽器的額外數據。它是作為 jQuery 事件對象的 data 屬性傳遞給事件監聽器的。
下面看具體的例子。
使用 jQuery 事件對象
對某些事件的處理,我們可能需要從事件對象中獲取當前事件的進一步信息。
假設頁面上有個輸入框只允許輸入數字。當用戶輸入的字符為非數字字符時,頁面能夠自動將其”過濾”掉,即在輸入框中不顯示這些無效的字符。實現這樣 的功能就需要從表示用戶輸入的 keypress 事件對象中獲取用戶當前所按的鍵的鍵盤編碼值,以便找出相應的字符。代碼如清單 15 所示:
清單 15.使用 jQuery 事件對象
$( "#txtVerifyCode" ).bind( "keypress" , function (evt){ var keyCode=evt.which; //從事件對象中獲取當前按鍵的編碼值 var char=String.fromCharCode(keyCode) ; //將按鍵的編碼轉換為相應的字符 if (!/\d/.test(char)){ //當前輸入的字符不是數字字符 //調用事件對象的 preventDefault 方法,取消事件的默認行為,此處即取消輸入。 evt.preventDefault(); } }); |
從上面的例子(在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=JqEvtObj.htm)可以看出,具體是什么按鍵觸發了 keypress 事件的信息可以從 jQuery 封裝的 jQuery 對象的相應屬性 keyCode 中獲取。而 jQuery 在調用我們的事件監聽器時會將其封裝的事件對象作為唯一參數傳遞給事件監聽器。
向事件監聽器傳遞額外參數
下面看一個向監聽器傳遞額外參數的例子。
假設現在有個能夠在頁面中顯示提示信息的函數,其定義如下:
function showTip(msg){ $( '#divTips' ).html(msg); //顯示具體的提示內容 } |
頁面上有兩個按鈕,它們被單擊的時候頁面上分別會顯示不同的提示信息。那么,我們可以編寫如下的事件監聽器:
清單 16.從事件對象中獲取額外數據
function showTipHandler(evt){ var data=evt.data; //獲取額外參數 /*額外參數是一個我們根據需要的自定義對象。這里,我們假設這個對象有個 msg 屬性。 它表示希望要顯示的提示信息。 */ var msg=data.msg; showTip(msg); } |
那么,我們就可以在事件綁定的時候,使用上面定義的事件監聽器。并定義其額外參數。代碼如下:
清單 17.向事件監聽器傳遞額外數據
$( '#tip1' ).bind( 'click' ,{msg: '中文提示' },showTipHandler); $( '#tip2' ).bind( 'click' ,{msg: 'English tip' },showTipHandler); |
從上面的例子(在線例子:http://blog.viscenthuang.info/jQuery/page/CodeDemo.htm?code=EvtObjExtraData.htm)可以看出,在調用 bind 方法綁定事件監聽器時指定的額外數據(即 bind 方法的第 2 個參數)可以被事件監聽器通過訪問事件對象的 data 屬性來獲取。這個特性在使用統一個事件監聽器出來多個元素的事件時顯得很有用。
事件綁定的簡便方法
通過 bind 方法實現事件綁定,需要我們在 bind 方法的第一個參數中指定具體的事件名。
jQuery 也提供一些簡便的事件綁定方法。這些方法就以所要處理的事件名命名。
比如,清單 15 中的代碼可以寫成:
$( "#txtVerifyCode" ).keypress( function (evt){ //這里是事件處理代碼 }); |
取消事件綁定
如果要取消某個事件監聽器。則可以使用 unbind 方法。
下面的例子演示了取消 ID 為 btnTest 的按鈕上的事件監聽器 handleClick 。代碼如下:
清單 18.取消事件綁定
$( "#btnEvtBind" ).click(handleClick); //按鈕 btnTest 被單擊后,btnEvtBind 按鈕不再能夠響應 click 事件 $( "#btnTest" ).click( function (){ //使得 handleClick 監聽器不再起作用 $( "#btnEvtBind" ).unbind( "click" ,handleClick); }); |
調用 unbind 方法時,如果不指定第二個參數,則 jQuery 會取消監聽第一個參數所指定的事件的所有監聽器。若沒有指定任何參數,則 jQuery 會取消選擇器表達式匹配的所有元素上所有監聽器。
總結
本文講解了 jQuery 的語法、選擇器及其事件處理 API。這些是 jQuery 的核心,也是使用 jQuery 及學習本系列教程后續內容的基礎。雖然這些內容不是很難掌握,但編程畢竟是一種技能,而非知識,技能是需要通過練習才能獲得的。因此,建議您利用本教程提 供的在線例子,自己動手試著去做一下練習,并在練習過程中體會教程所講解的內容。
原文出處: IBM Developerworks(黃文海)