| jQuery 教學 - 基礎篇[前言]
 jQuery 是一套 JavaScript 的 Library,因此,你必須稍具 JavaScript 的基礎,至少寫過一些 JavaScript 才比較容易上手,並且看得懂後續的教學。jQuery 的核心程式並非包山包海、什麼都可以幫你做,相反地,jQuery 主要是用在 DOM 文件的操作,包含「快速選取元素(Element)」並且「做一些事情」,快速選取元素可以讓你一次選取單一或多個的元素,然後你可以將這些被選取的元素做一些改變,例如隱藏、顯示等等。此外 jQuery 的核心程式還加強了非同步傳輸(AJAX)以及事件(Event)的功能,讓你更容易操作遠端文件及事件。
 
 以上看得出來 jQuery 是針對 JavaScript 內在不足的地方加以增進,你仍然需要自己寫一些程式來完成你需要的各種功能,不同的是,正確地使用了 jQuery 可以讓你的程式碼更精簡、更優雅的表達出來,這在後續的範例中可以看到,更重要的是,應該也會讓你更快速的開發出你要的功能。
 
 或許你會想說,在這個 Web 2.0 的時代,我需要多點漂亮、絢麗的 Widgets 來裝飾我的網站,就像 Yahoo UI 或 ExtJS 提供的那些功能一樣,jQuery 有嗎?其實 jQuery 的設計上有考慮到這類擴展性的問題,目前 jQuery 的 plugin 已經有上百個了,你也不一定要完全自己動手寫,上 jQuery 官方網站找找看,或許你需要的功能別人已經幫你做好了。以 UI 來講, jQuery 跟 UI 相關的 plugins 已經做過了一些整合,目前獨立發佈為 jQuery UI (
 http://ui.jquery.com/),如果你之前沒聽過 jQuery UI,建議你上去網站上看一下展示的範例,嗯,雖然可能還有一些 bug 存在,但是整體來說已經有相當的水準了,或許你會對 jQuery 更有興趣了。
 
 以下的教學內容,主要是擷取了 jQuery 作者 John Resig 的一篇簡報 "Building Interactive
 Prototypes with jQuery" 的內容加以調整並註解,希望能以比較忠實的方式來呈現 jQuery 的設計含意。
 
 
 [初探]
 
 jQuery 怎麼用來「快速選取元素」並且「做一些事情」呢?請看看程式碼:
 $("div").addClass("special");錢記號 $ 是 jQuery 的物件,使用 $("div") 就是用 jQuery 來選取元素,這個範例可以選取文件內所有的 <div> 元素。後面接著的 .addClass("special") 就是用來做一些事情,這個範例是將先前所選取到的所有元素都加上一個名為 "special" 的 class。也就是透過 $("div").addClass("special")的語法,可以讓你一次幫文件上有的 <div> 元素都加入 special 的 class。
 
 請注意喔,剛剛的例子可以針對已選取的多個元素做批次的操作,也就是說如果文件上有三個 <div>,那就會一次找出三個 <div> 並且全部套用後續的動作。這和你原本自己使用 JavaScript 來寫程式有很大的差異,原本自己寫可能會需要用到迴圈之類的語法,而 jQuery 的函數大多具有批次處理的功能,光是這點就可以讓你的程式更簡潔了。
 
 關於錢記號 $ 將會是你學習及使用 jQuery 的過程中最重要的物件(或者你要把 $ 當成一個函數也可以,事實上也是這樣),使用方式就像剛剛你看到的,用來找元素用的,把參數帶入即可。或許你不習慣錢記號也可以當成函數名稱,那麼你也可以用 jQuery 這個名字,錢記號其實是被當成 jQuery 的縮寫,讓你的函數看起來更簡潔一些,如果你要自己設定另外一個縮寫,例如 $j,也是可以的,這部份後續再解釋,先看看已下的範例,結果將會和上面的範例是一模一樣的:
 jQuery("div").addClass("special");[選取元素]
 
 前面的例子使用 $("div") 來選取元素,帶入的參數 div 是表示你要找的元素,這是 CSS 選擇器(CSS Selector) 的語法,就如同 CSS 在做排版和外觀所使用的選擇器語法一樣。jQuery 所支援的 CSS Selector 包含了 CSS 1、CSS2 以及仍未正式發佈的 CSS3,此外透過 plugin 還可支援常用的 XPath 語法,善用這些 CSS、XPath 語法就可以很容易地找到你要處理的網頁元素,底下來看看更多的範例。
 
 這是一段原始的 HTML:
 
 <div id="body">以下用一連串的範例,以藍色字體展示一些基本的語法並且以深色字顯示文件中會被選取的元素。<h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 
 
 $("div")
 <div id="body">
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 解釋:選取所有 <div>
 
 
 $("#body")
 <div id="body">
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 
 解釋:選取 id 為 body 的元素
 
 
 $("div#body")
 <div id="body">
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 解釋:選取 id 為 body 的 <div>
 
 
 $("div.contents p")
 <div id="body">
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 
 </div>
 </div>
 解釋:選取 class 為 contents 的 <div> 所包住的所有下層的 <p>
 
 
 $("div > div")
 <div id="body">
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 解釋:選取被 <div> 包住的下一層 <div>
 
 
 $("div:has(div)")
 <div id="body">
 
 <h2>Some Header</h2>
 <div class="contents">
 <p>...</p>
 <p>...</p>
 </div>
 </div>
 解釋:和前一個範例相反,這邊是選取至少有包住一個 <div> 的 <div>
 
 
 [做一些事情]
 
 前一段的教學中介紹了如何使用 jQuery 來選取元素,其中大部份的語法都是可以讓你快速地一次選取多個元素,接下來當然就是要來對這些選取到的元素做些改變囉。透過 jQuery 內建的函數,你可以:
 
 對 DOM 進行操作,例如對文件節點的新增或修改添加事件處理做一些基本的視覺效果,例如隱藏、顯示、下拉顯示、淡出淡入等等使用 AJAX 傳送表單內容或取得遠端文件
 
 [範例1] 選取所有有 target 屬性的 <a>,並且在其節點下加入一段文字。
 $("a[target]").append(" (Opens in New Window)");這是一段原始的 HTML :
 <a href="http://jsgears.com">jsGears</a>選取有 target 屬性並加入文字後的結果:<a href="http://google.com" target="_blank">Google</a>
 <a href="http://amazon.com" target="_blank">Amazon</a>
 
 <a href="http://jsgears.com">jsGears</a>[範例2] 選取 id 為 body 的元素,並且修改兩個 css 屬性。<a href="http://google.com" target="_blank">Google (Opens in New Window)</a>
 <a href="http://amazon.com" target="_blank">Amazon (Opens in New Window)</a>
 
 $("#body").css({這是一段原始的 HTML :border: "1px solid green",
 height: "40px"
 });
 <div id="body">選取 id 為 body 的元素並修改 css 後的結果(示意):...
 </div>
 
 <div id="body" style="border: 1px solid green; height: 40px">[範例3] 在網頁上的表單送出時加入一個判斷,如果 username 這個欄位是空值的話,就顯示 help 這個區塊內的文字。...
 </div>
 
 $("form").submit(function() {可作用在類似以下的 HTML,一開始 span.help 是隱藏的,如果沒有輸入 username,才會顯示:if ($("input#username").val() == "")
 $("span.help").show();
 });
 <style type="text/css">[範例4] 當 user 點選 id 為 open 的連結時,顯示 id 為 menu 的區塊,並回傳 false 避免瀏覽器真的換頁。.help {display: none}
 </style>
 <form>
 <label for="username">請輸入大名</label>
 <input type="text" id="username" name="username" />
 <span class="help">這個欄位必填喔</span>
 </form>
 
 $("a#open").click(function() {可作用在類似以下的 HTML:$("#menu").show();
 return false;
 });
 <style type="text/css">[範例5] 將 id 為 menu 的區塊以下拉布幕的動態效果快速顯示:#menu {display: none}
 </style>
 <a id="open" href="#">控制面板</a>
 <ul id="menu">
 <li><a href="#1">控制面板首頁</a></li>
 <li><a href="#2">編輯個人資料</a></li>
 <li><a href="#3">個人空間管理</a></li>
 </ul>
 
 $("#menu").slideDown("fast");可作用在類似以下的 HTML,原本隱藏的選單會以動態下拉的方式顯示出來:
 <style type="text/css">[範例6] 將所有的 <div> 漸變為寬 300px、文字與邊界寬 20px#menu {display: none}
 </style>
 <ul id="menu">
 <li><a href="#1">控制面板首頁</a></li>
 <li><a href="#2">編輯個人資料</a></li>
 <li><a href="#3">個人空間管理</a></li>
 </ul>
 
 $("div").animate({可作用在類似以下的 HTML:width: '300px',
 padding: '20px'
 }, 'slow');
 <div style="width: 100px; border: solid 1px red;">PS. jQuery 核心程式的 animate 函數能改變的元素屬性並不多,但是可以透過其他 plugin 提供更多的動態效果。Hello world!
 </div>
 
 [範例7] 動態效果的 callback 的範例,將所有的 <div> 以 0.5 秒的動態效果隱藏後,再以 0.5 秒的動態效果顯示。hide() 的第二個參數就是一個 callback 函數,其中 $(this) 是原本程式所處理的各個元素。
 
 $("div").hide(500, function(){可作用在類似以下的 HTML:// $(this) 是每一個各別的 <div>
 $(this).show(500);
 });
 <div style="width: 100px; border: solid 1px red;">[範例8] 取得 sample.html 並將找出文件內所有 <div> 下一層的 <h1> 填入原本文件 id 為 body 的元素內Hello world!
 </div>
 <div style="width: 100px; border: solid 1px red;">
 jsGears.com!
 </div>
 
 $("#body").load("sample.html div > h1");這是一段原始的 HTML :<div id="body"></div>sample.html 的片段: 
 <div>執行程式碼之後的結果:<h1>Hello world!</h1>
 <h2>This is H2</h2>
 <h1>jsGears.com!</h1>
 </div>
 
 <div id="body">[範例9] 透過 getJSON() 取得 JSON 格式的資料,並透過 callback 函數處理資料<h1>Hello world!</h1>
 <h1>jsGears.com!</h1>
 </div>
 
 $.getJSON("test.json", function(data){這是一段原始的 HTML:for (var idx in data)
 $("#menu").append("<li>" + data[idx] + "</li>");
 });
 <ul id="menu">test.json 的內容:<li>項目1</li>
 </ul>
 
 [執行程式碼之後的結果:"Hello world!",
 "jsGears.com!"
 ]
 
 <ul id="menu"><li>項目1</li>
 <li>Hello world!</li>
 <li>jsGears.com!</li>
 </ul>
 
 [連續使用函數]
 
 jQuery 很重要的一個特性是可以連續地使用函數(Chaining),當你選取了一個或一組的元素後,可以連續對這些元素進行多個處理。以下範例會將所有的 <div> 隱藏,修改文字顏色為藍色,再將 <div> 以下拉布幕的效果顯示出來:
 
 $("div").hide();這樣的三行程式碼可以用以下一行的程式碼取代,結果會是完全相同的:$("div").css("color", "blue");
 $("div").slideDown();
 $("div").hide().css("color", "blue").slideDown();是否感到很神奇呢?在 jQuery 的架構設計上,大部分的函數都會在處理完該做的事情後,再將原本傳入的元素給回傳回去,因此函數都可以連續這樣一個接著一個的使用。還記得一開始所說的 jQuery 可以讓你的程式碼更精簡嗎?看了上面的一些範例後,現在應該有點感覺了吧。
 講到 jQuery 的函數連續使用,有兩個很重要的函數必須在此介紹一下。第一個是 end(),這個函數執行後,會回傳「前一組找到的元素」。另一個是 find(),這個函數的用法如同使用 $() 找文件內的元素一樣是帶入 CSS 選擇器,執行後回傳找到的元素,不同的是 $() 是找整個文件,而 find() 是根據先前找到的元素再找其底下的元素,像是一個再過濾的功能。
 
 $("ul.open")                // [ ul, ul, ul ]上面這一段程式碼連續使用多個函數,且透過 end() 和 find() 來分別對不同的元素進行操作,詳細的步驟解釋如下:.children("li")           // [ li, li, li ]
 .addClass("open")         // [ li, li, li]
 .end()                    // [ ul, ul, ul ]
 .find("a")                // [ a, a, a ]
 .click(function(){
 $(this).next().toggle();
 return false;
 })                        // [ a, a, a ]
 .end();                   // [ ul, ul, ul ]
 
 找出文件內所有 class 為 open 的 <ul>過濾出下一層的所有 <li>對這些 <li> 新增一個 class回前一次搜尋的結果,也就是所有的 <ul>再找出底下所有的 <a>對 <a> 新增事件處理回前一次搜尋的結果
 
 [待續]
 
 jQuery 基礎篇的教學到此囉,希望對初學者能有所幫助,如果任何誤謬之處,也希望大家不吝指正。後續應該會再規劃一些 jQuery 實用的 plugin 介紹,作為基礎篇的延續,敬請期待。
 |