譯者說:鄰近期末,大部份的基礎教學內容已講授終了,在進行比較大型的項目訓練之前,如果能讓學生了解乃至遵守1些前端開發的編碼規范將會是1件非常成心義的事情。因此,本博客準備于近期整理1個編碼規范與最好實踐的系列文章,包括html、css、javascript、jquery、php等,希望能對大家有所幫助。
-----------------------------------------------------------------------------------------
本文給大家顯現的如何書寫更好的jQuery代碼的相干規范和最好實踐,不包括javascript方面的規范,有好的意見和建議請大家到我的博客留言賜教,或看看jQuery API的速查表(cheat sheet)。
選擇器
- 盡量的使用效力更高的ID選擇器,由于僅僅使用“document.getElementById()”實現。
- 使用類(Class)選擇器時,不要使用元素類型(Element Type),看看績效差異。
var $products = $("div.products"); // SLOW
var $products = $(".products"); // FAST
- 對ID->child的方式,使用find的方式比嵌套選擇器高效,由于第1個選擇器不用使用Sizzle這個選擇器引擎,更多信息。
// BAD, a nested query for Sizzle selector engine
var $productIds = $("#products div.id");
// GOOD, #products is already selected by document.getElementById() so only div.id needs to go through Sizzle selector engine
var $productIds = $("#products").find("div.id");
- 選擇器右側越具體越好,左側相反,更多信息。
// Unoptimized
$("div.data .gonzalez");
// Optimized
$(".data td.gonzalez");
- 避免過度具體,更多信息,看看績效差異。
$(".data table.attendees td.gonzalez");
// Better: Drop the middle if possible.
$(".data td.gonzalez");
- 給你的選擇器1個范圍。
// SLOWER because it has to traverse the whole DOM for .class
$('.class');
// FASTER because now it only looks under class-container.
$('.class', '#class-container');
- 避免使用全局選擇器,更多信息。
$('div.container > *'); // BAD
$('div.container').children(); // BETTER
- 避免隱含的全局選擇器,更多信息。
$('div.someclass :radio'); // BAD
$('div.someclass input:radio'); // GOOD
- 不要使用重復、交叉使用ID選擇器,由于單獨的ID選擇將使用更高效的document.getElementById()方式,更多信息。
$('#outer #inner'); // BAD
$('div#inner'); // BAD
$('.outer-container #inner'); // BAD
$('#inner'); // GOOD, only calls document.getElementById()
DOM操作
- 處理現存元素之前,先剝離,處理以后再附加,更多信息。
var $myList = $("#list-container > ul").detach();
//...a lot of complicated things on $myList
$myList.appendTo("#list-container");
- 使用字符串聯接符或array.join(),比.append高效,更多信息,看看績效差異。
// BAD
var $myList = $("#list");
for(var i = 0; i < 10000; i++){
$myList.append("<li>"+i+"</li>");
}
// GOOD
var $myList = $("#list");
var list = "";
for(var i = 0; i < 10000; i++){
list += "<li>"+i+"</li>";
}
$myList.html(list);
// EVEN FASTER
var array = [];
for(var i = 0; i < 10000; i++){
array[i] = "<li>"+i+"</li>";
}
$myList.html(array.join(''));
- 不要操作空缺對象,更多信息。
// BAD: This runs three functions before it realizes there's nothing in the selection
$("#nosuchthing").slideUp();
// GOOD
var $mySelection = $("#nosuchthing");
if ($mySelection.length) {
$mySelection.slideUp();
}
事件
- 每一個頁面只使用1次document的ready事件,這樣便于調試與行動流跟蹤。
- 盡可能不要使用匿名函數綁定事件,由于匿名函數不利于調試、保護、測試、重用,更多信息。
$("#myLink").on("click", function(){...}); // BAD
// GOOD
function myLinkClickHandler(){...}
$("#myLink").on("click", myLLinkClickHandler);
- 對document ready事件處理函數,盡可能不用匿名函數,理由同上。
$(function(){ ... }); // BAD: You can never reuse or write a test for this function.
// GOOD
$(initPage); // or $(document).ready(initPage);
function initPage(){
// Page load event where you can initialize values and call other initializers.
}
- document ready事件處理函數可以包括在外部文件中,然后通過頁內js的方式調用。
<script src="my-document-ready.js"></script>
<script>
// Any global variable set-up that might be needed.
$(document).ready(initPage); // or $(initPage);
</script>
- 不要使用html中的行動語法調用事件(html的onclick事件屬性),那簡直是調試者的噩夢。始終使用jquery來綁定、刪除事件是1件愜意的事情。
<a id="myLink" href="#" onclick="myEventHandler();">my link</a> <!-- BAD -->
$("#myLink").on("click", myEventHandler); // GOOD
- 可能的時候,使用自定義事件,我們可以很方便的消除該事件綁定而不影響其他事件。
$("#myLink").on("click.mySpecialClick", myEventHandler); // GOOD
// Later on, it's easier to unbind just your click event
$("#myLink").unbind("click.mySpecialClick");
- 當你給多個對象綁定相同的事件時,可使用事件委派。事件委派中,當我們給父對象綁定事件后,匹配選擇器的后代都可以綁定該事件,不管該后代原來就有,還是新增元素。
$("#list a").on("click", myClickHandler); // BAD, you are attaching an event to all the links under the list.
$("#list").on("click", "a", myClickHandler); // GOOD, only one event handler is attached to the parent.
Ajax
- 避免使用.getJson()和.get(), 像它的名字昭示的那樣使用$.ajax()。
- 不要在https站點上使用http要求,最好使用獨立性URL(不包括http:和https:,直接以//開頭)。
- 不要在要求URL上放置參數,使用data對象傳遞參數。
// Less readable...
$.ajax({
url: "something.php?param1=test1?m2=test2",
....
});
// More readable...
$.ajax({
url: "something.php",
data: { param1: test1, param2: test2 }
});
- 最好明確指定數據類型(dataType)以便于明確處理的數據類型(參見下例)。
- 對Ajax加載的內容使用事件委派,事件委派可以很好的解決新增元素的事件綁定問題,更多信息。
$("#parent-container").on("click", "a", delegatedClickHandlerForAjax)
- 使用Promise interface(不知道怎樣翻,請大家賜教),更多案例。
$.ajax({ ... }).then(successHandler, failureHandler);
// OR
var jqxhr = $.ajax({ ... });
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);
- Ajax樣例,更多信息。
var jqxhr = $.ajax({
url: url,
type: "GET", // default is GET but you can use other verbs based on your needs.
cache: true, // default is true, but false for dataType 'script' and 'jsonp', so set it on need basis.
data: {}, // add your request parameters in the data object.
dataType: "json", // specify the dataType for future reference
jsonp: "callback", // only specify this to match the name of callback parameter your API is expecting for JSONP requests.
statusCode: { // if you want to handle specific error codes, use the status code mapping settings.
404: handler404,
500: handler500
}
});
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);
效果和動畫
- 采取克制和1致的方法去實現動畫。
- 不要過度使用動畫效果,除非是用戶體驗所需。嘗試使用簡單的show/hide,slideUp/slideDown等方法切換對象,嘗試使用‘fast’,'slow'和‘medium’。
插件
- 優先選用具有良好支持、測試、社區支持的插件。
- 檢查該插件與您所用jQuery版本的兼容性。
- 任意可復用組件都應當構成插件,看看jQuery插件的樣本代碼。
鏈式操作
- 將鏈式操作看成變量緩存和多選擇器要求的替換方式。
$("#myDiv").addClass("error").show();
- 當鏈式操作超過3個或由于事件綁定變得復雜時,使用換行和縮進提高鏈式操作的可讀性。
$("#myLink")
.addClass("bold")
.on("click", myClickHandler)
.on("mouseover", myMouseOverHandler)
.show();
- 對長的鏈式操作來講,也能夠把中間對象緩存成1個變量。
雜項
- 使用字面對象傳遞參數。
$myLink.attr("href", "#").attr("title", "my link").attr("rel", "external"); // BAD, 3 calls to attr()
// GOOD, only 1 call to attr()
$myLink.attr({
href: "#",
title: "my link",
rel: "external"
});
- 不要混寫css與jQuery。
$("#mydiv").css({'color':red, 'font-weight':'bold'}); // BAD
.error { color: red; font-weight: bold; } /* GOOD */
$("#mydiv").addClass("error"); // GOOD
- 不用使用棄用的方法,了解每一個新版本的棄用方法,并且避免使用它,非常重要。
- 必要的時候可以混合jQuery和原生js,了解表現jQuery和原生js的表現差異。
$("#myId"); // is still little slower than...
document.getElementById("myId");
參考文獻
- 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 Cheatsheet: http://lab.abhinayrathore.com/jquery-cheatsheet/
- jQuery Plugin Boilerplate: http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/