jQuery程式設計的最佳實踐
載入jQuery
1.堅持使用CDN來載入jQuery,這種別人伺服器免費幫你託管檔案的便宜幹嘛不佔呢。點選檢視使用CDN的好處,點此檢視一些主流的jQuery CDN地址。
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/jquery-1.11.0.min.js" type="text/javascript"><\/script>')</script>
2.安全起見,最好還是提供一個本地備份以便在無法從遠端CDN伺服器獲取jQuery時網站也能工作,如上面程式碼所示。詳情見此。
3.使用裸協議的URL(也就是說去掉http:或者https:),如上面程式碼展示的那樣。
4.如果可能,儘量將你的JavaScript和jQuery程式碼放到頁面底部。詳情移步這裡,或者檢視一個HTML5頁面標準模板。
5.該使用哪個版本?
- 如果你想相容IE678請不要用2.x的版本
- 針對極少數不用考慮相容性的幸運兒,極力推薦使用最新版本的jQuery
- 當從CDN伺服器載入jQuery時,最好把版本寫全(比如1.11.0而不是1.11或者直接寫個1)
- 千萬莫重複載入
6.如果你同時還使用了其他JS框架諸如Prototype, MooTools, Zepto云云,因為他們也使用了$符號,所以你就不要再用美刀符號來進行jQuery 編碼了,而請用'jQuery'代替。並且呼叫$.noConflict()保證不會有衝突出現。
7.要檢測瀏覽器對一些新特性是否支援,請用Modernizr。插播廣告:論為何不檢測瀏覽器
關於變數
1.jQuery型別的變數最好加個$字首。
2.時常將jQuery選擇器返回的內容存進變數以便重用
var $products = $("div.products"); // 慢 var $products = $(".products"); // 快
3.使用駝峰命名
關於選擇器
1.儘量ID選擇器。其背後機理其實是呼叫原生的document.getElementById(),所以速度較其他選擇器快。
2.使用類選擇器時不要指定元素的型別。不信你看這個效能比較
var $products = $("div.products"); // 慢 var $products = $(".products"); // 快
3.ID父親容器下面再查詢子元素請用.find()方法。這樣做快的原因是透過id選擇元素不會使用Sizzle引擎。詳情看這裡
4.多級查詢中,右邊儘量指定得詳細點而左邊則儘量簡單點。瞭解更多
// 醜陋 $("div.data .gonzalez"); // 最佳化後 $(".data td.gonzalez");
$(".data table.attendees td.gonzalez"); // 好的方式:去掉了中間的冗餘 $(".data td.gonzalez");
6.指定選擇的上下文。
// 劣質的程式碼:因為需要遍歷整個DOM來找到.class $('.class'); // 高品程式碼:因為只需在指定容器範圍內進行查詢 $('.class', '#class-container');
7.不要使用萬能選擇器。檢視具體闡釋
$('div.container > *'); // 差 $('div.container').children(); // 棒
8.警惕隱式的萬能選擇器。省略的情況下其實使用的就是*號萬用字元。更多資訊
$('div.someclass :radio'); // 差 $('div.someclass input:radio'); // 棒
9.ID已經表示唯一了,背後使用的是document.getElementById(),所以不要跟其他選擇器混搭了。
$('#outer #inner'); // 髒 $('div#inner'); // 亂 $('.outer-container #inner'); // 差 $('#inner'); // 乾淨利落,後臺只需呼叫document.getElementById()
DOM操作相關
1.操作任何元素前先將其從文件解除安裝,完了再貼回去。這事兒還能說細點
var $myList = $("#list-container > ul").detach(); //...一大堆對$myList的處理 $myList.appendTo("#list-container");
2.程式碼裡將HTML組織好後再一次性貼到DOM中去。具體來說,效能比較
// 這樣不好 var $myList = $("#list"); for(var i = 0; i < 10000; i++){ $myList.append("<li>"+i+"</li>"); } // 這樣好 var $myList = $("#list"); var list = ""; for(var i = 0; i < 10000; i++){ list += "<li>"+i+"</li>"; } $myList.html(list); // 但這樣更好 var array = []; for(var i = 0; i < 10000; i++){ array[i] = "<li>"+i+"</li>"; } $myList.html(array.join(''));
3.不要處理不存在的元素。詳情
// 無良的做法:jQuery後臺要跑完三個函式後才會知道這個元素其實根本不存在 $("#nosuchthing").slideUp(); // 應該這樣 var $mySelection = $("#nosuchthing"); if ($mySelection.length) { $mySelection.slideUp(); }
事件相關
1.一個頁面只寫一個文件ready事件的處理程式。這樣程式碼既清晰好除錯,又容易跟蹤程式碼的程式。
2.不要用匿名函式來做事件的回撥。匿名函式不易除錯維護測試和複用。或許你想較真,看看這裡吧
$("#myLink").on("click", function(){...}); // 表這樣 // 這樣 function myLinkClickHandler(){...} $("#myLink").on("click", myLinkClickHandler);
3.處理文件ready事件的回撥也不要用匿名函式,匿名函式不易除錯維護測試和複用:(
$(function(){ ... }); // 糟糕的做法:無法利用此函式也無法為其寫測試用例 // 好的做法 $(initPage); // 抑或 $(document).ready(initPage); function initPage(){ // 這裡你可以進行程式的初始化了 }
4.進一步,最好也將ready事件的處理程式放到外部檔案中引入到頁面,而頁面中內嵌的程式碼只需呼叫即可。
<script src="my-document-ready.js"></script> <script> // 初始化一些必要的全域性變數 $(document).ready(initPage); // 抑或 $(initPage); </script>
5.千萬不要寫內聯到HTML的JS程式碼,這是除錯的夢魘!應該總是用jQuery來繫結事件自帶程式,這樣也方便隨時動態地取消繫結。
<a id="myLink" href="#" onclick="myEventHandler();">my link</a> <!--不好 -->
$("#myLink").on("click", myEventHandler); // GOOD
6.如果可能儘量在繫結事件處理程式時使用一個名稱空間,這樣可以方便地取消繫結而不會影響其他繫結。
$("#myLink").on("click.mySpecialClick", myEventHandler); // 不錯 // 之後,讓我們優雅地解除繫結 $("#myLink").unbind("click.mySpecialClick");
非同步操作
1.直接用$.ajax()而表去用.getJson() 或 .get(),因為jQuery內部還是將其轉為前者
2.不要對HTTPS站點使用HTTP去發起請求,最好乾脆就不要指定(將HTTP或者HTTPS從你的URL中移除)
3.不要在連結裡面嵌引數,請使用專門的引數設定來傳遞
// 不易閱讀的程式碼... $.ajax({ url: "something.php?param1=test1¶m2=test2", .... }); // 更易閱讀... $.ajax({ url: "something.php", data: { param1: test1, param2: test2 } });
4.儘量指明資料型別以便你自己清楚要處理什麼樣的資料(見下方會提到的Ajax模板)
5.對於非同步動態載入的內容,最好使用代理來繫結事件處理程式。這樣的好處是對於之後動態載入的元素事件同樣有效。你或許想瞭解更多
$("#parent-container").on("click", "a", delegatedClickHandlerForAjax);
6.使用Promise模式。更多例子
$.ajax({ ... }).then(successHandler, failureHandler); // 抑或 var jqxhr = $.ajax({ ... }); jqxhr.done(successHandler); jqxhr.fail(failureHandler);
7.標準的Ajax模板一分。追尋根源
var jqxhr = $.ajax({ url: url, type: "GET", // 預設為GET,你可以根據需要更改 cache: true, // 預設為true,但對於script,jsonp型別為false,可以自行設定 data: {}, // 將請求引數放這裡. dataType: "json", // 指定想要的資料型別 jsonp: "callback", // 指定回撥處理JSONP型別的請求 statusCode: { // 如果你想處理各狀態的錯誤的話 404: handler404, 500: handler500 } }); jqxhr.done(successHandler); jqxhr.fail(failureHandler);
動畫與特效
1.保持一個始終如一風格統一的動畫實現
2.緊遵使用者體驗,不要濫用動畫特效
- 使用簡潔的顯示隱藏,狀態切換,滑入滑出等效果來展示元素
- 使用預設值來設定動畫的速度'fast','slow',或者400(中等速度)
外掛相關
1.始終選擇一個有良好支援,完善文件,全面測試過並且社群活躍的外掛
2.注意所用外掛與當前使用的jQuery版本是否相容
3.一些常用功能應該寫成jQuery外掛。一分jQuery外掛的編寫模板
鏈式句法
1.除了用變數將jQuery選擇器返回的結果儲存,還可以利用好鏈式呼叫。
$("#myDiv").addClass("error").show();
2.當鏈式呼叫多達3次以上或程式碼因繫結回撥略顯複雜時,使用換行和適當的縮排來提高程式碼的可讀性。
$("#myLink") .addClass("bold") .on("click", myClickHandler) .on("mouseover", myMouseOverHandler) .show();
3.對於特別長的呼叫最好還是用變數儲存下中間結果來簡化程式碼。
其他
1.使用物件字面量來傳遞引數
$myLink.attr("href", "#").attr("title", "my link").attr("rel", "external"); // 糟糕:呼叫了三次attr // 不錯,只呼叫了一次attr $myLink.attr({ href: "#", title: "my link", rel: "external" });
2.不要將CSS與jQuery雜揉
$("#mydiv").css({'color':red, 'font-weight':'bold'}); // 不好
.error {/* 不錯 */ color: red; font-weight: bold; }
$("#mydiv").addClass("error");
3.時刻關注官方Changelog,不要使用摒棄了的方法。點此檢視所有廢棄的方法
4.適時地使用原生JavaScript。一些與此有關的效能比較
$("#myId"); // 多少還是會遜色於... document.getElementById("myId");
REFERENCE
- jQuery Performance: http://learn.jquery.com/performance/
- jQuery Learn: http://learn.jquery.com
- jQuery API Docs: http://api.jquery.com/
- jQuery Coding Standards and Best Practice: http://www.jameswiseman.com/blog/2010/04/20/jquery-standards-and-best-practice/
- jQuery Plugin Boilerplate: http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/
相關文章
- Python程式設計規範+最佳實踐Python程式設計
- Java程式設計師的八個最佳實踐Java程式設計師
- Laravel最佳實踐–事件驅動程式設計Laravel事件程式設計
- Laravel 最佳實踐 -- 事件驅動程式設計Laravel事件程式設計
- Laravel最佳實踐 -- 事件驅動程式設計Laravel事件程式設計
- 函數語言程式設計最佳實踐函數程式設計
- TypeScript 資料模型層程式設計的最佳實踐TypeScript模型程式設計
- [01] C#網路程式設計的最佳實踐C#程式設計
- 設計微服務的最佳實踐微服務
- MaxCompute表設計最佳實踐
- 領域驅動設計最佳實踐--程式碼篇
- react 設計模式與最佳實踐React設計模式
- 13 個設計 REST API 的最佳實踐RESTAPI
- 資料庫設計的十個最佳實踐資料庫
- vSAN 設計、部署、運維最佳實踐運維
- Go程式設計實踐Go程式設計
- 一些通過SAPABAP程式碼審查得出的ABAP程式設計最佳實踐程式設計
- 設計出色API的最佳實踐與原則 - JamesAPI
- 高效前端程式設計實踐前端程式設計
- hadoop程式設計實踐(一)Hadoop程式設計
- 一些通過SAP ABAP程式碼審查得出的ABAP程式設計最佳實踐程式設計
- [分享]2021 年對 React 前端程式設計師的 10 個程式碼最佳實踐建議React前端程式設計師
- 阿里研究員谷樸:API 設計最佳實踐的思考阿里API
- 鴻蒙程式設計江湖:ArkTS開發綜合案例與最佳實踐鴻蒙程式設計
- 邊緣計算的最佳實踐
- Spring Boot中五個設計模式最佳實踐Spring Boot設計模式
- 敏捷最佳實踐:設計衝刺完整指南 -Useberry敏捷
- 最佳實踐:路徑路由匹配規則的設計與實現路由
- 如何培養良好的程式設計實踐程式設計
- Java併發程式設計實踐Java程式設計
- framebuffer應用程式設計實踐程式設計
- Golang 併發程式設計實踐Golang程式設計
- 資料庫設計中的6個最佳實踐步驟資料庫
- 來自Google資深工程師的API設計最佳實踐Go工程師API
- Node之道:設計、架構和最佳實踐 | Alex Kondov架構
- 異常值檢測!最佳統計方法實踐(程式碼實現)!⛵
- 程式設計實踐考試的入門模板程式設計
- 面向介面程式設計實踐之aspnetcoreapi的抽象程式設計NetCoreAPI抽象
- 資源成本雙最佳化!看 Serverless 顛覆程式設計教育的創新實踐Server程式設計