jQuery编码标准和最佳实践

这些都是一些常见的使用jQuery编写更好的代码的标准和最佳实践。这些标准不包括JavaScript的标准或最佳做法。

jQuery的加载

  1. 在页面中总是偿试从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>

    点击这里 列举了一些比较流行的jQuery CDN服务器。

  2. 使用备用方案从本地加载相同版本的jQuery文件,参考上面的代码。 更多信息
  3. 使用 相对的或协议无关的URL地址(不要使用http:或https:),参考上面的代码。
  4. 尽可能使JavaScript和jQuery引入代码放在页面的底端。 更多信息 这里有一个例子 HTML5 Boilerplate.
  5. 如何选择版本?
    • 如果你要支持IE6/7/8话,就不要使用jQuery 2.x
    • 对于新的项目,如果不用考虑插件兼容的问题,强烈推荐使用最新版本
    • 当你使用CND加载jQuery时,最好指定完整的版本号(如:1.11.0,而不要使用1.11或1)
    • 不要同时加载多个不同版本的jQuery
  6. 如果你同时使用其它的库,比如Prototype,Mootools,Zepto等使用$的库。最好不要使用$来调用jQuery函数,用jQuery代替。你可以使用$.noConflict()来将$保留给其它框架使用。
  7. 如需要使用更高级浏览器特性检测,可以使用 Modernizr

jQuery变量

  1. 所有的存储和缓存jQuery对象的变量名前添加 $ 前缀。
  2. 总是缓存jQuery选择器的结果到变量中,以便重用。
    var $myDiv = $("#myDiv");
    $myDiv.click(function(){...});
  3. 变量命名使用驼峰命名法。

选择器

  1. 尽可能使用ID选择器。它的速度更快,因为它使用的document.getElementById().
  2. 当使用class选择器时,不要在选择器中使用元素类型。 性能比较
    var $products = $("div.products"); // SLOW
    var $products = $(".products"); // FAST
  3. 使用find替代 ID->Child 内嵌选择器。.find稍微快一些,因为它需要Sizzle选择器引擎的检查。 更多信息
    // BAD, 使用Sizzle选择器引擎 获取内嵌查询
    var $productIds = $("#products div.id");
    
    // GOOD, #products 直接使用 document.getElementById()获取。只有 div.id 需要使用 Sizzle选择器引擎
    var $productIds = $("#products").find("div.id");
  4. 多级选择器时,在左边使用更少的限定条件。 更多信息
    // 未优化的
    $("div.data .gonzalez");
    
    // 优化的
    $(".data td.gonzalez");
  5. 避免过度使用限定条件 更多信息性能比较
    $(".data table.attendees td.gonzalez");
    
    // Better: 尽可能去掉中间限定条件.
    $(".data td.gonzalez");
  6. 指定选择器的上下文
    // SLOWER 遍历了所有的DOM查找.class
    $('.class');
    
    // FASTER 只查找class-container容器中的.
    $('.class', '#class-container');
  7. 避免使用全体的选择器。 更多信息
    $('div.container > *'); // BAD
    $('div.container').children(); // BETTER
  8. 避免隐式的全体选择器。 更多信息
    $('div.someclass :radio'); // BAD
    $('div.someclass input:radio'); // GOOD
  9. 不要一次选择多个ID或ID选择器与其它选择器嵌套使用。ID选择器是使用document.getElementById()处理的,因此不要把ID选择器和其它选择器混合使用。
    $('#outer #inner'); // BAD
    $('div#inner'); // BAD
    $('.outer-container #inner'); // BAD
    $('#inner'); // GOOD, 只调用document.getElementById()

DOM操作

  1. 总是分离任何已存在的元素在操作之前,完成后再附加回去。 更多信息
    var $myList = $("#list-container > ul").detach();
    //...a lot of complicated things on $myList
    $myList.appendTo("#list-container")
  2. 在.append()之前,先使用字符串拼接或array.join()
    // 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(''));
  3. 操作元素之前,检测元素是否存在。 更多信息
    // BAD: 该操作在意识到元素不存在时,已经运行了3个函数
    $("#nosuchthing").slideUp();
    
    // GOOD
    var $mySelection = $("#nosuchthing");
    if ($mySelection.length) {
        $mySelection.slideUp();
    }

事件

  1. 每个页面只使用一个Document Ready函数。这样更容易调试和跟踪程序流程。
  2. 不要在事件上附加匿名函数。匿名函数很难调试、维护、测试或重用。 更多信息
    $("#myLink").on("click", function(){...}); // BAD
    
    // GOOD
    function myLinkClickHandler(){...}
    $("#myLink").on("click", myLinkClickHandler);
  3. Document Ready事件处理器最好不要是匿名函数。再重复一遍,匿名函数很难调试、维护、测试或重用。
    $(function(){ ... }); // BAD: 你永远不能重用或给该函数写一个测试用例.
    
    // GOOD
    $(initPage); // or $(document).ready(initPage);
    function initPage(){
        // 页面加载事件时,你可以在这里初始化值或调用其它初始化函数。
    }
  4. Document Ready事件处理器应包含在外部文件并且内联JavaScript可以调用ready函数在初始化函数运行后。
    <script src="my-document-ready.js"></script>
    <script>
        // 初始化任何需要的全局变量
        $(document).ready(initPage); // or $(initPage);
    </script>
  5. 不要使用在HTML中使用行为标记(JavaScript内联),它们在调试时就是恶梦。总是使用jQuery来绑定事件,这样容易动态的附加或删除事件。
    <a id="myLink" href="#" onclick="myEventHandler();">my link</a> <!-- BAD -->
    
    $("#myLink").on("click", myEventHandler); // GOOD
  6. 尽可能在事件上使用自定义 命名空间。这样更容易精确的解除绑定的事件,避免影响其它绑定到DOM元素上的事件。
    $("#myLink").on("click.mySpecialClick", myEventHandler); // GOOD
    // 稍后,更容易只解除你的client函数的绑定
    $("#myLink").unbind("click.mySpecialClick");

Ajax

  1. 避免使用.getJson() 或 .get(),简单的使用$.ajax()作为内部调用。
  2. 不要使用http请求https网站。使用结构化的URL地址(不要在URL中使用http或https)
  3. 不要把请求参数放在URL中,发送时使用数据对象来设置。
    // 可读性差...
    $.ajax({
        url: "something.php?param1=test1&param2=test2",
        ....
    });
    
    // 可读性更好...
    $.ajax({
        url: "something.php",
        data: { param1: test1, param2: test2 }
    });
  4. 指定dataType参数,这样让你更容易知道你处理的数据种类。(看下面Ajax模板的例子)
  5. 在给使用Ajax动态加载的内容附加事件时,使用委托事件处理器,这样可以处理,在页面加载以后增加到document中的内容。 更多信息
    $("#parent-container").on("click", "a", delegatedClickHandlerForAjax);
  6. 使用Promise接口: 更多示例
    $.ajax({ ... }).then(successHandler, failureHandler);
    
    // OR
    var jqxhr = $.ajax({ ... });
    jqxhr.done(successHandler);
    jqxhr.fail(failureHandler);
  7. Ajax调用示例: 更多信息
    var jqxhr = $.ajax({
        url: url,
        type: "GET", // 默认使用的 GET 但你可以根据需要使用其它类型
        cache: true, // 默认使用 true, 当 dataType 为 'script' 或 'jsonp'时,设置为 false, 根据你的使用决定.
        data: {}, // 在data对象中增加你的请求参数.
        dataType: "json", // 指定 dataType 备查
        jsonp: "callback", // 只指定匹配的 callback 参数与 JSONP 请求中一致.
        statusCode: { // 如果你想处理指定的错误代码,使用这个状态码映射设置.
            404: handler404,
            500: handler500
        }
    });
    jqxhr.done(successHandler);
    jqxhr.fail(failureHandler);

动画和特效

  1. 使用一致的方法来实现动画效果。
  2. 不要过度使用动态效果,除非有UX需求驱动。
    • 偿试使用简单的show/hide, toggle 和 slideUp/slideDown 函数来开关元素。
    • 偿试使用预定义的动画时间间隔 “slow”,”fast” 或400(如 medium)

插件

  1. 总是选择有良好的文档、测试和社区支持的插件。
  2. 检查插件与你使用的jQuery版本的兼容性。
  3. 任何一般可重用的组件应该实现为jQuery插件。 点击这里查看jQuery插件引用代码。

链式调用

  1. 使用链式调用替代缓存变量和多选择器调用。
    $("#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"); // BAD, 3 次调用 attr()
    // GOOD, 只有 1 次调用 attr()
    $myLink.attr({
        href: "#",
        title: "my link",
        rel: "external"
    });
  2. 不要使用jQuery来设置样式。
    $("#mydiv").css({'color':red, 'font-weight':'bold'}); // BAD
    .error { color: red; font-weight: bold; } /* GOOD */
    $("#mydiv").addClass("error"); // GOOD
  3. 不要使用废弃的方法。始终要注意避免使用新版本中废弃的方法。 点击这里这里列出了废弃的方法。
  4. 有需要时,结合使用jQuery和原生的JavaScript。看看这里给出的性能比较示例: http://jsperf.com/document-getelementbyid-vs-jquery/3
    $("#myId"); // 该方法还是稍微的慢一些
    document.getElementById("myId");

资源

Tagged: ,

Comments are closed.