jQuery編碼規范與最佳實踐

jopen 9年前發布 | 47K 次閱讀 jQuery Ajax框架

前端開發whqet,csdn,王海慶,whqet,前端開發專家

翻譯自:http://lab.abhinayrathore.com/

翻譯人員:前端開發whqet,意譯為主,不當之處歡迎大家指正。

譯者說:臨近期末,大部分的基礎教學內容已經講解完畢,在進行比較大型的項目訓練之前,如果能讓學生了解甚至遵循一些前端開發的編碼規范將會是一件非常有意義的事情。因此,本博客準備于近期整理一個編碼規范與最佳實踐的系列文章,包括html、css、javascript、jquery、php等,希望能對大家有所幫助。

------------------------------------------------------------

--我參加了博客之星評選,如果你喜歡我的博客,求投票~~http://vote.blog.csdn.net/blogstar2014/details?username=whqet#content

-----------------------------------------------------------------------------------------

本文給大家呈現的如何書寫更好的jQuery代碼的相關規范和最佳實踐,不包括javascript方面的規范,有好的意見和建議請大家到我的博客留言賜教,或者看看jQuery API的速查表(cheat sheet)。

加載jQuery

  1. 在您的頁面中優先使用CDN的方式,CDN方式的優點在這里,這里有比較流行的jQueryCDN列表清單(由于國內goolge限制問題,建議使用國內的CDN,例如百度的CDN)。
  2. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="js/jquery-2.1.1.min.js" type="text/javascript"><\/script>')</script>
  3. 利用上面代碼,預備一個相同版本的本地jQuery庫,以備不時之需。
  4. 使用如上所示的協議獨立性URL(去掉http:或https:,直接以//開頭,例如‘//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js’)
  5. 如果可能,盡量保持所有的JS代碼和jQuery在頁面底部加載,更多信息或看個示例HTML5 Boilerplate
  6. 使用哪個版本?
  7. 如果你要兼容ie6、7、8,不要使用jQuery2.x版本
    對于新的應用來說,如果不存在兼容性問題,強烈建議使用最新版本
    從CDN加載jQuery時,指定你需要加載版本的完整版本號(例如,使用1.11.0而不是1.11或者1)
    不要加載多個jQuery版本
    不要使用jquery-latest.js
  8. 如果你的頁面同時用到了類似于Prototype、MooTools、Zepto等這些同樣使用$的類庫,要使用jquery替代$,我們可以使用$.noConflict()把$的控制權還給其他庫。
  9. 使用Modernizr實現高級的瀏覽器特征檢測。
  10. </ol>

    jQuery變量

    1. 所有用于存儲、緩存jQuery對象的變量應該以$前綴命名。
    2. 最好把使用選擇器返回的jQuery對象緩存到變量里,以便重用。
    3. var $myDiv = $("#myDiv");
      $myDiv.click(function(){...});
    4. 使用駝峰法命名變量。
    5. </ol>

      選擇器


      1. 盡可能的使用效率更高的ID選擇器,因為僅僅使用“document.getElementById()”實現。
      2. 使用類(Class)選擇器時,不要使用元素類型(Element Type),看看績效差異
      3. var $products = $("div.products"); // SLOW
        var $products = $(".products"); // FAST
      4. 對于ID->child的方式,使用find的方式比嵌套選擇器高效,因為第一個選擇器不用使用Sizzle這個選擇器引擎,更多信息
      5. // 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");</pre>

      6. 選擇器右邊越具體越好,左邊相反,更多信息
      7. // Unoptimized
        $("div.data .gonzalez");

        // Optimized $(".data td.gonzalez");</pre>

      8. 避免過度具體,更多信息,看看績效差異
      9. $(".data table.attendees td.gonzalez");

        // Better: Drop the middle if possible. $(".data td.gonzalez");</pre>

      10. 給你的選擇器一個范圍。
      11. // SLOWER because it has to traverse the whole DOM for .class
        $('.class');

        // FASTER because now it only looks under class-container. $('.class', '#class-container');</pre>

      12. 避免使用全局選擇器,更多信息
      13. $('div.container > *'); // BAD
        $('div.container').children(); // BETTER
      14. 避免隱含的全局選擇器,更多信息
      15. $('div.someclass :radio'); // BAD
        $('div.someclass input:radio'); // GOOD
      16. 不要使用重復、交叉使用ID選擇器,因為單獨的ID選擇將使用更高效的document.getElementById()方式,更多信息
      17. $('#outer #inner'); // BAD
        $('div#inner'); // BAD
        $('.outer-container #inner'); // BAD
        $('#inner'); // GOOD, only calls document.getElementById()
        </ol>

        DOM操作


        1. 處理現存元素之前,先剝離,處理之后再附加,更多信息
        2. var $myList = $("#list-container > ul").detach();
          //...a lot of complicated things on $myList
          $myList.appendTo("#list-container");
        3. 使用字符串連接符或者array.join(),比.append高效,更多信息,看看績效差異
        4. // 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(''));</pre>

        5. 不要操作空缺對象,更多信息
        6. // 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(); }</pre> </ol>

          事件


          1. 每個頁面只使用一次document的ready事件,這樣便于調試與行為流跟蹤。
          2. 盡量不要使用匿名函數綁定事件,因為匿名函數不利于調試、維護、測試、重用,更多信息
          3. $("#myLink").on("click", function(){...}); // BAD

            // GOOD function myLinkClickHandler(){...} $("#myLink").on("click", myLLinkClickHandler);</pre>

          4. 對于document ready事件處理函數,盡量不用匿名函數,理由同上。
          5. $(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. }</pre>

          6. document ready事件處理函數可以包含在外部文件中,然后通過頁內js的方式調用。
          7. <script src="my-document-ready.js"></script>
            <script>
                // Any global variable set-up that might be needed.
                $(document).ready(initPage); // or $(initPage);
            </script> 
          8. 不要使用html中的行為語法調用事件(html的onclick事件屬性),那簡直是調試者的噩夢。始終使用jquery來綁定、刪除事件是一件愜意的事情。
          9. <a id="myLink" href="#" onclick="myEventHandler();">my link</a> <!-- BAD -->

            $("#myLink").on("click", myEventHandler); // GOOD</pre>

          10. 可能的時候,使用自定義事件,我們可以很方便的解除該事件綁定而不影響其他事件。
          11. $("#myLink").on("click.mySpecialClick", myEventHandler); // GOOD
            // Later on, it's easier to unbind just your click event
            $("#myLink").unbind("click.mySpecialClick");    
          12. 當你給多個對象綁定相同的事件時,可以使用事件委派。事件委派中,當我們給父對象綁定事件后,匹配選擇器的后代都可以綁定該事件,無論該后代原來就有,還是新增元素。
          13. $("#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. 
            </ol>

            Ajax


            1. 避免使用.getJson()和.get(), 像它的名字昭示的那樣使用$.ajax()。
            2. 不要在https站點上使用http請求,最好使用獨立性URL(不包含http:和https:,直接以//開頭)。
            3. 不要在請求URL上放置參數,使用data對象傳遞參數。
            4. // Less readable...
              $.ajax({
                  url: "something.php?param1=test1?m2=test2",
                  ....
              });

              // More readable... $.ajax({ url: "something.php", data: { param1: test1, param2: test2 } });</pre>

            5. 最好明確指定數據類型(dataType)以便于明確處理的數據類型(參見下例)。
            6. 對Ajax加載的內容使用事件委派,事件委派可以很好的解決新增元素的事件綁定問題,更多信息
            7. $("#parent-container").on("click", "a", delegatedClickHandlerForAjax)
                  
            8. 使用Promise interface(不知道怎么翻,請大家賜教),更多案例
            9. $.ajax({ ... }).then(successHandler, failureHandler);

              // OR var jqxhr = $.ajax({ ... }); jqxhr.done(successHandler); jqxhr.fail(failureHandler); </pre>

            10. Ajax樣例,更多信息
            11. 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); 
              </ol>

              效果和動畫


              1. 采用克制和一致的方法去實現動畫。
              2. 不要過度使用動畫效果,除非是用戶體驗所需。嘗試使用簡單的show/hide,slideUp/slideDown等方法切換對象,嘗試使用‘fast’,'slow'和‘medium’。

              插件


              1. 優先選用具有良好支持、測試、社區支持的插件。
              2. 檢查該插件與您所用jQuery版本的兼容性。
              3. 任意可復用組件都應該形成插件,看看jQuery插件的樣本代碼

              鏈式操作


              1. 將鏈式操作看成變量緩存和多選擇器請求的替代方式。
              2. $("#myDiv").addClass("error").show();
                    
              3. 當鏈式操作超過三個或者因為事件綁定變得復雜時,使用換行和縮進提高鏈式操作的可讀性。
              4. $("#myLink")
                    .addClass("bold")
                    .on("click", myClickHandler)
                    .on("mouseover", myMouseOverHandler)
                    .show();
              5. 對于長的鏈式操作來說,也可以把中間對象緩存成一個變量。
              6. </ol>

                雜項


                1. 使用字面對象傳遞參數。
                2. $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"
                  });
                3. 不要混寫css與jQuery。
                4. $("#mydiv").css({'color':red, 'font-weight':'bold'}); // BAD
                  .error { color: red; font-weight: bold; } /* GOOD */
                  $("#mydiv").addClass("error"); // GOOD
                5. 不用使用棄用的方法,了解每個新版本的棄用方法,并且避免使用它,非常重要。
                6. 必要的時候可以混合jQuery和原生js,了解表現jQuery和原生js的表現差異
                7. $("#myId"); // is still little slower than...
                  document.getElementById("myId");    
                  </ol>

                  參考文獻


                  </div>

                  Enjoy it.

                  <p>
                      ----------------------------------------------------------
                  </p>
                  

                  </div>

                  前端開發whqet,關注web前端開發,分享相關資源,歡迎點贊,歡迎拍磚。
                  ---------------------------------------------------------------------------------------------------------


                   本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
                   轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
                   本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!