今天的主角是 jQuery
很多人看到 jQuery 會直接聯想到「落伍」的老科技,甚至搞不好最近才開始學前端的人,會連這個名詞都沒聽過。
雖然現在 jQuery 的討論熱度大不如前,但能夠橫掃十幾年前端界的 jQuery,你是否曾好奇過它到底強在哪?
在沒有 jQuery 的時代,網頁其實還是很單純的,比起現在隨便就是電商、網頁遊戲、SaaS 等高互動性的網站,還記得以前的網頁都是什麼類型嗎?
史萊姆的第一個家 (居然還在啊感動!!! 還特別保留了古早味的版本)
奇摩家族
無名小站
網路時代剛興起的時代,這種論壇、相簿、形象官網等類型的網站充斥在線上,互動性比較低,比較單方向地將資訊與資源呈現給使用者,從使用者的角度,頂多做到註冊、留言、搜尋等動作。
某種程度上來說,前端要做的事情不多,將後端給的資料與畫面呈現出來即可,也不太會有畫面局部刷新、動態變化等,在這個情況下,開發者處理的通常是「死」的資料,丟到畫面上能看就好。
當然,此時手機上網也不是大宗,沒有什麼 RWD 的概念。
隨著時代與科技演進,前端的資料開始慢慢「活」了起來,開始有些互動操作,比如:
同時,RWD 的需求也慢慢崛起,同樣的網頁在不同的手機平板裝置上,該如何不跑版,並且符合小裝置的視覺習慣。
以及最可怕的,同樣的網頁在不同的瀏覽器上,會有相容性的問題,往往需要為了特定瀏覽器,多寫幾個 switch case 去判斷,甚至即便是同一個瀏覽器,不同版號有時也是天差地別,堪稱是工程師噩夢QQ
jQuery is a fast, small, and feature-rich JavaScript library.
沒錯,jQuery 不是程式語言,也不是前端框架(framework),它是 library!
jQuery 是 JavaScript 的第三方函式庫,引用 jQuery 之後,就可以使用裡面大量的函式,其中大多數是關於選取、操作 HTML DOM 節點,以及衍伸出來的 CSS 樣式設定。
最廣為人知的就是 jQuery 的選擇器,也就是那個錢字號($
):
// JavaScript
document.getElementById("ID") // 因為只會取得一個節點,所以 getElement 沒有 s
document.getElementsByClassName("className") // 注意到語法比上面那行多一個 s
// jQuery
$("#ID")
$(".className") // 無論 ID 還是 className 都是回傳一個 List,較一致
除了大幅減少冗長又沒什麼規律的語法,jQuery 選擇器比照 CSS selector 的語法,用 #
代表選取 id,用 .
代表選取 class name,立刻得到設計師族群青睞!jQuery 加 10 分 !
後來原生的 JavaScript 也是有像這種語法:
// JavaScript
document.querySelector("#ID")
document.querySelectorAll(".className")
雖然也是用 CSS selector,不過一樣冗長,且一個回傳 DOM 節點,另一個則是 NodeList,這點不一致不免還是要花精力去記憶。
另外,更厲害的是 jQuery 具有 chain 的特性,由於每次執行 jQuery 的函式,大多都會回傳 jQuery 的物件,因此可以像鎖鏈一樣串接,再度拿這個回傳的物件去執行下一個 jQuery 函式,要選取 children
、parent
、sibilings
節點都是易如反掌。
有了這麼方便的選擇器,選到 DOM 節點之後,當然就很好對畫面上的元素進行一些修改,例如像這樣:
$( "ul.level-2" ).children().css( "background-color", "red" );
會發現 jQuery 的語法整句串下來,非常容易解讀,沒什麼贅字,甚至沒寫過的人,光用看的搞不好都可以猜意思。
其他更厲害的語法就不多說了,用法簡單到,在當時完全是設計師跳來前端的新手村,甚至很容易搞混以為 jQuery 的寫法就是 JavaScript XD
$.each
的寫法很像我們現在在用的 forEach
$( "li" ).each(function( index ) {
console.log( index + ": " + $( this ).text() );
});
$.ajax
的寫法有夠簡潔,比起更古早的 XMLHttpRequest
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
// Request complete.
});
// 我已經無法直視以前的 XMLHttpRequest 了...
const result = document.querySelector('.result');
function reqOnload () {
const data = JSON.parse(this.responseText);
var email = data.results[0].email;
result.textContent = email;
}
function reqError (err) {
console.log('錯誤', err)
}
// 宣告一個 XHR 的物件
var request = new XMLHttpRequest();
// 定義連線方式
request.open('get', 'https://randomuser.me/api/', true);
// 送出請求
request.send();
// 如果成功就執行 reqOnload()
request.onload = reqOnload;
// 失敗就 reqError()
request.onerror = reqError;
$.click
、$.animate
都是使用者與頁面互動的利器
$( "#clickme" ).click(function() {
$( "#book" ).animate({
opacity: 0.25,
left: "+=50",
height: "toggle"
}, 5000, function() {
// Animation complete.
});
});
針對 RWD 的問題,jQuery 相關的另一個 library 也提供了很棒的解法 - jQuery Mobile,雖然 jQuery mobile 已於 2021 年 10 月停止 support,不過仍然是在這十年間提供很不錯的 pattern 供大家學習。
以往各個瀏覽器有各自的實作,會導致同樣的 code 在不同瀏覽器有不同行為,支援度不一。但 jQuery 其實在背後幫我們統一了,讓我們不用寫一大堆判斷式(尤其是面對 IE 各種版本時...)。
整體來說,jQuery 這種比較直覺,比較偏向 imperative (命令式) 的寫法,若沒有透過良好的封裝,很容易會寫出狀態互相依賴的程式碼,換句話說,面對規模較大的程式架構,是比較不利的。
這也是為什麼 jQuery 近幾年會慢慢退潮的原因,現在的程式規模都相當龐大,更傾向於使用「資料導向」的框架來解決,要透過 jQuery 這種「DOM 導向」的函式庫,很容易會撞牆。
因此或許 jQuery 是更適合局部小專案,甚至在教導非工程師的族群時,反而 jQuery 的寫法是很容易被理解並運用的。
jQuery 是我出社會後第一個吃飯工具,但才轉眼幾年過去,學習了 React 之後,已經愈來愈把 jQuery 淡忘了,但偶爾還是會回想起,寫 jQuery 會讓我有一種「寫什麼都可以立刻得到畫面效果」,那種「呼風喚雨」的感受XD 其實在我剛初學時,是滿大的動力
還滿慶幸自己是先學 jQuery,不然如果直接就碰到現在一堆框架,搞不好那個學習曲線就直接把我壓倒了XD 也藉這個機會一步步走過前端的成長史,希望可以用這篇文,讓一些覺得 jQuery 很落伍的人「想像」一下,那個 jQuery 橫掃前端的年代。
深入現代前端開發
技術雜談:為什麼要用 (或不用) jQuery