1.堅持使用CDN來加載jQuery,這種別人服務(wù)器免費幫你托管文件的便宜干嘛不占呢。點擊查看使用CDN的好處,點此查看一些主流的jQuery CDN地址。
<script type="text/javascript" src="http://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>下面一行代碼是檢測jQuery這個全局對象是否存在,存在則已經(jīng)加載完成,不存在則加載本地的jQuery庫(保證下載不到的用戶能獲取到)
2.安全起見,最好還是提供一個本地備份以便在無法從遠(yuǎn)程CDN服務(wù)器獲取jQuery時網(wǎng)站也能工作,如上面代碼所示。詳情見此。
3.使用裸協(xié)議的URL(也就是說去掉http:或者h(yuǎn)ttps:),如上面代碼展示的那樣。(很多網(wǎng)站都轉(zhuǎn)向HTTPS協(xié)議了,為了保證不出錯最好不寫協(xié)議,讓轉(zhuǎn)發(fā)的自己判斷)
4.如果可能,盡量將你的JavaScript和jQuery代碼放到頁面底部。詳情移步這里,或者查看一個HTML5頁面標(biāo)準(zhǔn)模板。
5.該使用哪個版本?
6.如果你同時還使用了其他JS框架諸如PRototype, MooTools, Zepto云云,因為他們也使用了$符號,所以你就不要再用美刀符號來進(jìn)行jQuery 編碼了,而請用'jQuery'代替。并且調(diào)用 $.noConflict() 保證不會有沖突出現(xiàn)(還可以選擇是否讓出 jQuery 全局對象)。
7.要檢測瀏覽器對一些新特性是否支持,請用Modernizr(一個檢測CSS3和HTML5特性的JS腳本,會在body處添加一些檢測的結(jié)果)。插播廣告:論為毛不檢測瀏覽器
1.jQuery類型的變量最好加個$前綴。
2.時常將jQuery選擇器返回的內(nèi)容存進(jìn)變量以便重用(這里涉及到性能的問題,一個jQuery數(shù)組對象后面其實擁有大量的變量屬性,大量使用非常耗費系統(tǒng)資源,特別對瀏覽器來說,瀏覽器的內(nèi)存資源非常寶貴,這里用到了緩存的概念)
var $products = $("div.products"); // 慢var $products = $(".products"); // 快3.使用駝峰命名(這里說的是小駝峰命名如 myDiv 這樣的)
1.盡量ID選擇器。其背后機(jī)理其實是調(diào)用原生的 document.getElementById(),jQuery的ID選擇器是調(diào)用原生的這個方法,其他的則用到了document.querySelectorAll()方法,老式瀏覽器還要用Sizzle選擇器引擎模擬編譯過程匹配一大遍代碼才可以模擬實現(xiàn)document.querySelectorAll的類似功能,非常耗費內(nèi)存資源。
2.使用類選擇器時不要指定元素的類型。不信你看這個性能比較
這里要理解Sizzle選擇器引擎的原理,類選擇器會優(yōu)先檢測document.getElementsByClassName()方法,如果沒有的話會使用document.getElementsByTagName()原生方法模擬實現(xiàn)(也是很耗費內(nèi)存的)。
var $products = $("div.products"); // 慢var $products = $(".products"); // 快3.使用find()方法對id->child進(jìn)行選擇,.find()方法更快因為第一個選擇器處理沒有進(jìn)過Sizzle選擇器引擎。
因為 $ ('#id') 這樣的選擇器會用document.getElementById() 方法,可以減少Sizzle選擇器引擎的分詞壓力(選擇器越多分詞的過程就越繁瑣,運行的時間就會更久)和減少閉包的函數(shù)數(shù)量(會將函數(shù)構(gòu)成閉包鏈駐留在內(nèi)存中以便后面調(diào)用,jQuery犧牲了部分空間換取了執(zhí)行速度快的目的)。
總的來說就一句話,將用ID選擇器和用其他選擇器的查找分離。
// 不好的做法,對Sizzle選擇器引擎用了嵌套的查詢var $productsIds = $("#products div.id");// 好的做法,#product已經(jīng)通過document.getElementById()獲取到,只有div.id需要通過Sizzle選擇器引擎獲取var $productsIds = $("#products").find("div.id");4.多級查找中,右邊的特殊性盡量指定得多點而左邊的特殊性則盡量少點。了解更多
這里這樣寫的原因是因為Sizzle選擇器引擎分詞構(gòu)成函數(shù)閉包鏈之后是采用反向調(diào)用的原理從選擇器的右邊開始調(diào)用之前匹配好的函數(shù)。選擇器越多需要調(diào)用的函數(shù)則越多,浪費的內(nèi)存越多和運行時間越長。
// 不好$("div.data .gonzalez");// 優(yōu)化后$(".data td.gonzalez");所以應(yīng)該要記得寫選擇器代碼的時候的原則:越少選擇器越好,能獲取到你要的元素就可以。而且詳細(xì)的選擇器應(yīng)該放到右邊。
5.避免冗余,選擇器越少越好,以能獲取到你想要的范圍為準(zhǔn)。詳情或者查看性能比較
$(".data table.attendees td.gonzalez"); // 好的方式:去掉了中間的冗余$(".data td.gonzalez");6.指定選擇器的上下文 ( jQuery是有一個context參數(shù)可以縮小選擇范圍的,默認(rèn)為document )。
// 劣質(zhì)的代碼:因為需要遍歷整個DOM來找到.class$('.class');// 高品代碼:因為只需在指定容器范圍內(nèi)進(jìn)行查找$('.class', '#class-container');7.不要使用萬能選擇器,萬能選擇器會匹配非常多的TAG。查看具體闡釋
$('div.container > *'); // 差$('div.container').children(); // 棒8.警惕隱式的萬能選擇器。省略的情況下其實使用的就是*號通配符。更多信息
$('div.someclass :radio'); // 差$('div.someclass input:radio'); // 棒9.ID已經(jīng)表示唯一了,背后使用的是document.getElementById(),所以不要跟其他選擇器混搭了。
$('#outer #inner'); // 臟$('div#inner'); // 亂$('.outer-container #inner'); // 差$('#inner'); // 干凈利落,后臺只需調(diào)用document.getElementById()1.操作任何元素前先將其從文檔卸載,完了再貼回去。這里減少了訪問DOM元素的次數(shù)有利于提高性能。這事兒還能說細(xì)點
var $myList = $("#list-container > ul").detach();//...一大堆對$myList的處理$myList.appendTo("#list-container");2.使用字符串連接(指+)或者array.join()方法而不是.append()方法。這里也是因為.append()方法用到了DOM中的appendChild方法的原因。所以性能不太好。具體來說,性能比較
// 不好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(''));性能提高有一點需要記住的,就是訪問DOM接口的時候。為什么要緩存得到的變量?就是減少訪問DOM接口,可以將DOM訪問看作數(shù)據(jù)庫訪問,每訪問一次就需要消耗一些資源。
3.不要處理不存在的元素。詳情
// 無良的做法:jQuery后臺要跑完三個函數(shù)后才會知道這個元素其實根本不存在$("#nosuchthing").slideUp();// 應(yīng)該這樣var $mySelection = $("#nosuchthing");if ($mySelection.length) {    $mySelection.slideUp();}1.一個頁面只寫一個文檔 ready 事件的處理程序。這樣代碼既清晰好調(diào)試,又容易跟蹤代碼的過程。
2.不要用匿名函數(shù)來綁定事件。匿名函數(shù)不易調(diào)試維護(hù)測試和復(fù)用。看看這里吧
$("#myLink").on("click", function(){...}); // BAD,雅蠛蝶不要這樣 // GOODfunction myLinkClickHandler(){...}$("#myLink").on("click", myLinkClickHandler);3.處理文檔ready事件也不要用匿名函數(shù),在說一次,匿名函數(shù)不利于調(diào)試、維護(hù)、測試和復(fù)用 :(
$(function(){ ... }); // 糟糕的做法:無法復(fù)用此函數(shù)也無法為其寫測試用例 // 好的做法$(initPage); // 或者 $(document).ready(initPage);function initPage(){    // 寫頁面加載事件的地方}4.進(jìn)一步,最好也將ready事件的處理程序放到外部文件中引入到頁面,而頁面中內(nèi)嵌的代碼只需調(diào)用即可,(復(fù)用性大大提高)。
<script src="my-document-ready.js"></script><script>	// 初始化一些必要的全局變量	$(document).ready(initPage); // 或者 $(initPage);</script>5.千萬不要寫內(nèi)聯(lián)函數(shù)到HTML的JS代碼,這是調(diào)試的夢魘!應(yīng)該總是用jQuery來綁定事件自帶程序,這樣也方便隨時動態(tài)地綁定(復(fù)用性)和取消綁定(操作簡單),還有一點是有利于調(diào)試和測試。
<a id="myLink" href="#" onclick="myEventHandler();">my link</a> <!--不好 -->$("#myLink").on("click", myEventHandler); // GOOD6.如果可能使用自己的一個事件命名空間(custom namespace),這樣可以方便地取消綁定而不會影響其他DOM元素的事件綁定。
$("#myLink").on("click.mySpecialClick", myEventHandler); // 不錯// 之后,讓我們優(yōu)雅地解除綁定$("#myLink").unbind("click.mySpecialClick");7.使用事件委托當(dāng)你要對多個元素綁定相同的時間的時候。事件委托允許我們用一個事件監(jiān)聽器(事件處理函數(shù)),綁定在父元素(也可以是祖先元素)上。這樣可以減少頁面元素綁定的事件處理函數(shù)的數(shù)量,減少內(nèi)存消耗和綁定的時間消耗。
$("#list a").on("click", myClickHandler); // BAD,你會給所有的a標(biāo)簽綁定事件// 好的做法,只有一個事件被綁定到祖先元素,然后再函數(shù)里面再進(jìn)行判別$("#list a").on("click", "a", myClickHandler);1.直接用$.ajax()而不要去用 .getJson()或 .get(),因為jQuery內(nèi)部還是將其轉(zhuǎn)為前者
2.不要對HTTPS站點使用HTTP發(fā)起請求,最好干脆就不要指定(將HTTP或者HTTPS從你的URL中移除)
3.不要在鏈接里面嵌參數(shù),請使用數(shù)據(jù)對象(data Object)來傳遞設(shè)置
// 不易閱讀的代碼...$.ajax({    url: "something.php?param1=test1¶m2=test2",    ....}); // 更易閱讀...$.ajax({    url: "something.php",    data: { param1: test1, param2: test2 }});4.盡量指明數(shù)據(jù)類型以便你自己清楚要處理什么樣的數(shù)據(jù)(見下面的Ajax標(biāo)準(zhǔn)模板)
5.對于異步動態(tài)加載(Ajax)的內(nèi)容,最好使用事件委托來綁定事件處理。這樣的好處是對于之后動態(tài)加載的元素事件同樣有效。你或許想了解更多
委托的優(yōu)點:對于后面添加到頁面的元素事件委托可以檢測得到。因為對祖先元素添加的一個事件,那么除非在執(zhí)行事件處理否則不會去關(guān)注頁面是否有什么。所以對動態(tài)新添加的元素就能重新檢測得到。
$("#parent-container").on("click", "a", delegatedClickHandlerForAjax);6.使用$.when()和.then()(Promise延遲方法),Promise延遲是屬于jQuery異步模塊里面的。更多例子
$.ajax({ ... }).then(successHandler, failureHandler); // 或者var jqxhr = $.ajax({ ... });jqxhr.done(successHandler);jqxhr.fail(failureHandler);7.標(biāo)準(zhǔn)的Ajax模板。追尋根源
var jqxhr = $.ajax({    url: url,    type: "GET", // 默認(rèn)為GET,你可以根據(jù)需要更改    cache: true, // 默認(rèn)為true,但對于script,jsonp類型為false,可以自行設(shè)置    data: {}, // 將請求參數(shù)放這里.    dataType: "json", // 指定想要的數(shù)據(jù)類型    jsonp: "callback", // 指定回調(diào)處理JSONP類型的請求    statusCode: { // 如果你想處理各狀態(tài)的錯誤的話        404: handler404,        500: handler500    }});jqxhr.done(successHandler);jqxhr.fail(failureHandler);1.保持一個統(tǒng)一的風(fēng)格和相同的動畫實現(xiàn)(這里是一些設(shè)計方面的東西,如果頁面動畫多且雜會顯得沒有整齊的美感,做過設(shè)計的童鞋應(yīng)該能懂作者想要表達(dá)什么)。
2.緊遵用戶體驗,不要濫用動畫特效(動畫特效應(yīng)該是由用戶體驗驅(qū)動的)
1.始終選擇一個有良好支持,完善文檔,全面測試過并且社區(qū)活躍的插件(怎么感覺是在說jQuery自己-_-!!)
2.注意所用插件與當(dāng)前使用的jQuery版本是否兼容
3.任何常用或者可以復(fù)用的功能都可以寫成jQuery插件。jQuery插件的編寫模板
1.除了用變量將jQuery選擇器返回的結(jié)果緩存,也可以用鏈?zhǔn)降膶懛ň彺娅@取到的jQuery對象再調(diào)用其它方法。(jQuery比較有特色的特點,返回的都是一個jQuery封裝成的數(shù)組對象,所以不管是一個還是多個元素都可以調(diào)用同一個方法)。當(dāng)然你也可以用.end()或者.addSelf()或者.addBack()(addSelf和addBack是一個函數(shù),都是指向addBack)來對jQuery的鏈?zhǔn)讲僮鬟M(jìn)行回滾(jQuery維護(hù)了一個鏈?zhǔn)降臈#?/span>
$("#myDiv").addClass("error").show();2.當(dāng)鏈?zhǔn)秸{(diào)用多達(dá)3次以上或代碼因綁定回調(diào)略顯復(fù)雜時,使用換行和適當(dāng)?shù)目s進(jìn)來提高代碼的可讀性。
$("#myLink")    .addClass("bold")    .on("click", myClickHandler)    .on("mouSEOver", myMouseOverHandler)    .show();3.對于特別長的調(diào)用最好還是用變量保存下中間結(jié)果來簡化代碼。
1.使用對象字面量來傳遞參數(shù)
$myLink.attr("href", "#").attr("title", "my link").attr("rel", "external"); // 糟糕:調(diào)用了三次attr// 不錯,只調(diào)用了一次attr$myLink.attr({    href: "#",    title: "my link",    rel: "external"});2.不要將CSS與jQuery雜揉
$("#mydiv").css({'color':red, 'font-weight':'bold'}); // BAD.error { /* GOOD */    color: red;    font-weight: bold;}$("#mydiv").addClass("error"); /* Good */3.不要使用摒棄了的方法,對一些公布的廢棄的方法項目里面最好避免使用。時刻關(guān)注官方Changelog。點此查看所有廢棄的方法
4.當(dāng)需要的時候適時地結(jié)合使用原生JavaScript。jQuery的$('#')與document.getElementById原生方法的性能比較
$("#myId"); // 多少還是會遜色于原生的方法,所以在一些注重性能的地方還是要寫原生的JavaScript代碼document.getElementById("myId");原文:Coding Standards & Best Practices http://lab.abhinayrathore.com/jquery-standards/
原文的reference
這篇文章是看了一篇譯文之后結(jié)合自己對jQuery的理解和感悟以及作者的譯文和jQuery官網(wǎng)的編程規(guī)范做了一些小修改而成的,這里很感謝譯文作者的貢獻(xiàn)。
主要用途是留給自己以后翻查和給一些jQuery新手看的。
新聞熱點
疑難解答