==== 文章說明 ================================================================== 作者: RZ Fang 最後修改:2012-10-01 轉載請註明出處: http://skyzone.url.tw 這篇教學是小弟自己在學習 JQuery 一段時間後, 試著依循自己學習過程,嘗試撰寫的入門教學文。 文章很粗淺的介紹 JQuery 的特性, 並透過簡單的函式舉例,直接點出 JQuery 的特性, 藉以讓 您快速領會 JQuery 的設計思維。 ==== 認識 JQuery =============================================================== 官網: http://jquery.com/ 宗旨: write less, do more. 寫越少的 Code,做更多的事情。 一個 Javascript API (Framework)。 解決多數 Javascript 在不同瀏覽器上的表現差異。 相容性往前一路支援到 IE6。(目前 1.8.0 仍是如此) AJAX 便利使用的大量實作。 運作效能極佳。 只有一個 JS 檔案。 檔案容量很小。 佈署方式超簡單。 所有功能的命名、設計符合直覺。 ==== 程式撰寫思維 ============================================================== 找一個對象,做一些事。 從 $ 號開始。 定位 -> 篩選 -> 偏移 -> 做事 串接式連續操作。 批次處理複數個對象。 ==== Selector ================================================================== $() 的括號中放置的有意義字串。 所謂有意義字串,是一種格式八成近似於 CSS 的文字宣告。 直接舉例最好理解。 $('div') 網頁全內容中的所有 div Element 所封裝成的 JQuery 物件。 符合 CSS 運作原理。 $('#SomeID') 一個 ID 為 SomeID 的 Element 所封裝成的 JQuery 物件。 符合 CSS 運作原理。 $('.SomeClass') 所有 Class 為 SomeClasss 的 Element 所封裝成的 JQuery 物件。 符合 CSS 運作原理。 $('[name=GJ]') 所有屬性中有 name 而且值為 GJ 的 Element 所封裝成的 JQuery 物件。 $('div.SomeClass') 所有 Class 為 SomeClasss 的 div Element 所封裝成的 JQuery 物件。 符合 CSS 運作原理。 ==== 層級式的 Selector ========================================================= 雖然 JQuery 擅長透過簡單語法快速找到 Element,但網頁全文搜尋終究有其瓶頸。 為了進一步提高搜尋效率,同時兼顧減少宣告定義的撰寫, Selector 也支援 CSS 的搜尋定位方式。 $('#SomeID div') 所有在 ID 為 SomeID 的 Elmenet 底下的 div Element。 包含子層級和孫層級。 從 #SomeID Element 開始搜尋,避免全文搜尋。 $('#SomeID > div') 所有在 ID 為 SomeID 的 Elmenet 下的子層級 div Element。 僅包含子層級。 從 #SomeID Element 開始搜尋,避免全文搜尋。 $('.SomeClass div') 所有在 Class 為 SomeClass 的 Element 下的所有子孫層級的 div。 只要 div 包含在 .SomeClass 之下,就會被納入。 從 .SomeClass Element 開始搜尋,避免全文搜尋。 Q: $('#SomeID > div.SomeClass span[name=GJ]') 代表什麼呢? A: 找出 ID 為 SomeID 的 Element , 在其下找出 Class 為 SomeClass 的 div Element, 在其下所有層級找出屬性 name 有定義且值為 GJ 的所有 span Element。 ==== Attribute & CSS =========================================================== 在透過 Selector 取得對象 Element(s) 所封裝的 JQuery 物件之後, 當然是因為要拿來做點事,例如換掉內容字體顏色、更換 Class 或 ID 等等。 JQuery 雖然將 Element 封裝成自己格式的物件,沒辦法再用 Javascript 的方式(函式), 但與此同時,JQuery 也提供了自己的函式:attr() 和 css()。 舉例: var JO = $('#SomeID'); // Selector 找到 Element。 var JO_Name = JO.attr('name'); // 取得 Element 的屬性 name 的值。 var JO_Color = JO.css('color'); // 取得 Element 的 CSS style - color 的值。 JO.attr('name', 'GJ'); // 設定 Element 的屬性 name 的值。 JO.css('color', '#ff0000'); // 設定 Element 的 CSS style - color 的值。 JO.attr({'name': 'GJ', 'class': 'SomeClass'}); // 設定 Element 的屬性 name & class 的值。 JO.css({'color': '#ff0000', 'border': '1px solid'}); // 設定 Element 的 CSS style - color & border 的值。 可以留意到,同樣是呼叫 attr() 或 css() 函式, 給一個字串時,表示是 Get; 給一個字串和一個值時,表示是 Set; 給一個物件時,表示針對物件內容,同時執行多個 Set。 ==== Traversing ================================================================ 往往在對 Element 操作時,不會單單只針對一個 Element 進行調整。 從 Selector 的運作邏輯來看,必須明確找到目標,但若有多個目標必須操作時, 則必須針對每個目標進行 Selector 搜尋。 舉一個例子: 希望設定一個 div 內容的字體顏色為紅色,但希望其下的第一個 span 字體為藍色。 若單用 Selector,則必須進行兩次的設定: $('div#SomeID').css('color', '#ff0000'); $('div#SomeID > span:first').css('color', '#0000ff'); 由 Selector 段落知道,一個 Selector 就代表一次檢搜。 如果期望上例能夠保持最佳效率,以 Selector 方式必然得在 span Element 上加上 ID。 上例尚屬單純,當情況夠複雜時,為每一個 Element 都加上 ID 恐怕是一件耗時的工作。 因此以 Traversing 輔助,變成是一種轉環的解決辦法。 承上例,用 Traversing 輔助時的作法: $('div#SomeID').css('color', '#ff0000') .children('span:first').css('color', '#0000ff'); 同樣寫了兩行 Code,但實際上只有第一行進行了 Selector 搜尋, 第二行則是延用第一行的搜尋結果,繼續延伸定位其它 Element。 以上例而言,就是從該 div 出發,去找其下的第一個 span,然後將之設定顏色為藍色。 ==== 串接式的 JQuery 操作 ====================================================== JQuery 大部分的設定函式,都會回傳該 JQuery 物件本身,這表示在一個函式呼叫後, 可立刻接著另一個函式呼叫。 在結合了 Selector 與 Traversing 後, JQuery 將對 Element 的搜尋、設定的彈性大大提升。 舉例來說: 對下面 HTML 結構進行調整,希望第一個,最後一個的顏色是紅色,其它為藍色。 <!--v Sample v--> <div id='SomeID'> <span>A</span> <span>B</span> <span>C</span> <span>D</span> <span>E</span> </div> <!--^ Sample ^--> 則 JQuery 可如此撰寫: $('div#SomeID > span').css('color', '#0000ff') .first().css('color': '#ff0000') .end() .last().css('color': '#ff0000'); ==== Event ===================================================================== 由於 JQuery 的事件將 Javascript 的事件再封裝,因此兩者並不完全相等, 甚至於可說是完全不同的東西。 因此在事件的處理上,必須很明確知道該事件是 JQuery 的還是 Javascript 的。 在此僅介紹常用的項目,並未涵蓋 JQuery 全部事件。 bind / unbind click live / die & delegate / undelegate ==== bind / unbind ==== bind 可說是 JQuery 事件註冊的最基本函式, 許多其它事件註冊函式其實都是轉呼叫 bind 實作而成。 bind 的基本用法如下: JO.bind([事件名稱字串], [事件觸發要執行的函式]); 如: $('div#SomeID').bind('click', function(Evt){ alert('被點了'); }); unbind 即 bind 的相反,但有數種使用方式產生不同的結果。 JO.unbind(); 將原本註冊在 JO 上的所有事件全部刪除。 JO.unbind('click'); 只刪除在 JO 上的 click 事件。 另外必須留意,JQuery 事件並不如同 Javascript 的事件, 可由後面的定義覆蓋掉前面的定義。 當針對一個 JQuery 物件連續定義相同事件時,每一個都會掛載,並在事件觸發時,全部執行。 以下兩段 Code 的效果是不同的: $('#SomeID').bind('click', function(Evt){ alert('被點了A'); }); $('#SomeID').bind('click', function(Evt){ alert('被點了B'); }); $('#SomeID').bind('click', function(Evt){ alert('被點了A'); }); $('#SomeID').unbind('click'); $('#SomeID').bind('click', function(Evt){ alert('被點了B'); }); ==== click ==== click 事件幾乎可註冊在所有 HTML 可視 Element 上。 承 bind 的介紹,事實上 click 在底層只是轉呼叫 bind('click') 而已。 然而一如 JQuery 的許多函式具有多數功能,click 亦擔任兩種不同的任務。 JO.click(function(){}); 當傳入 Callback 函式時,click 作為事件回呼的設定函式。 JO.click(); 當 click 不傳任何參數時,當作觸發事件。 在此僅介紹 click 事件,JQuery 基本重新實作了大部分的 Javascript 事件, 大抵不脫離前述的使用方式。 ==== live / die & delegate / undelegate ==== 如同 bind 與 unbind 相對一般,live 與 die 相對;delegate 與 undelegate 相對。 基本上二種用法類似,功能都是為動態 Element 註冊事件。 試想以下情況: 網頁上提供使用者建立自己的通訊錄,建立一筆資料後,旁邊會提供一顆刪除按鈕。 上述情況,開發者無法預期使用者會建立多少筆資料, 但只要有一筆資料,就必須提供一個刪除該筆的功能按鈕。 為完成該刪除按鈕的事件,在每次產生一筆新資料時, 就必須同時執行一段程式碼,將刪除功能註冊給按鈕的 click 事件。 當資料有 100 筆時,頁面中就有 100 顆按鈕,以及 100 個 click 事件。 透過 live 方避免掉反覆註冊的手續, 在 1.4 版後推出的 delegate 更一舉將事件的註冊量大幅降低。 由於 delegate 的效能遠超過 live,因此只介紹 delegate 原理。 承前例,delegate 在網頁一開始就在這些通訊錄資料的上層 Element 註冊事件, 透過 JQuery 事件向上層傳遞的原理, 所有刪除按鈕的 click 事件最終會傳遞到上層 Element 負責觸發, 然後才由 delegate 中的 selector 參數去分析觸發事件的來源 Element, 因此即使有 100 顆按鈕,但實際上只有 1 個事件。 ================================================================================