Ниже приведены основные стандарты и лучшие практики написания кода на jQuery. Они не включают стандарты и лучшие практики нативного JS.

jquery

Загрузка jQuery

1. Старайтесь использовать CDN для загрузки jQuery.

<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.html" type="text/javascript"><\/script>')</script>

Публичная CDN-библиотека Baidu должна быть самой быстрой во всех регионах Китая, и в ней много JS-библиотек. Рекомендуется всем.

<script src="../libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>

Сервис ускорения JS-библиотек Upyun имеет приличную скорость доступа в Китае, но, к сожалению, у него относительно мало JS-библиотек.

<script src="../upcdn.b0.upaiyun.com/libs/jquery/jquery-1.8.3.min.js"></script>

JS/CSS-библиотека Sina, также известная как публичная библиотека Sina SAE, имеет приличную скорость доступа в Китае и исчерпывающий набор JS-библиотек. Рекомендуется всем.

<script src="http://lib.sinaapp.com/js/jquery/1.8.3/jquery.min.js"></script>

Переменные jQuery

  • 1. Все переменные, которые используют или кэшируют объекты jQuery, должны начинаться с$префикс.
  • 2. Всегда кэшируйте объекты, возвращаемые селекторами jQuery, в локальные переменные для повторного использования.
  var $myDiv = $("#myDiv");
  $myDiv.click(function(){....});
  • 3. Используйте camelCase при именовании переменных.

Селекторы

  • 1. По возможности используйте ID-селекторы, так как внутренне они используютdocument.getElementById()。
  • 2. При использовании селекторов классов/псевдоклассов всегда добавляйте к селектору тип элемента, чтобы избежать сканирования всего DOM-дерева.
 // BAD 在整个DOM树中扫描"products"类名
var $products = $(".products");

// GOOD 只在DIV元素中扫描"products"类名
var $products = $("div.products");
  • 3. В селекторах ID > дочернего уровня используйтеfind()метод. Потому что первая половина селектора не использует движок селекторов Sizzle для поиска элементов.
// BAD, Sizzle选择器引擎查找层级
var $productIds = $("#products div.id");

// GOOD, 只有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. Добавляйте контекст к селекторам.
// 要扫描整个DOM树寻找
$('.class');

// 只在#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 используютdocument.getElementById(). Селекторы ID не нужно вкладывать.
$('#outer #inner'); // BAD
$('div#inner'); // BAD
$('.outer-container #inner'); // BAD
$('#inner'); // GOOD

Операции с DOM

  • 1. Всегда сначала отсоединяйте существующие элементы DOM, затем выполняйте операции и наконец присоединяйте их обратно к DOM.
var $myList = $("#list-container > ul").detach();
//...针对$myList的许多DOM操作
$myList.appendTo("#list-container");
  • 2. Используйте конкатенацию строк или 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(''));
  • 3. Не работайте с неизвестными элементами.
// BAD: 这个函数内部要先执行3个函数,才发现选择器选择到的可能是空内容
$("#nosuchthing").slideUp();

// GOOD
var $mySelection = $("#nosuchthing");
if ($mySelection.length) {
    $mySelection.slideUp();
}

Events

  • 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(){
  // Document ready里可以初始化变量和调用其他初始化函数
}
  • 4. Функции document ready следует размещать во внешних файлах, а после других настроек инициализации вызывайте эти функции во встроенном JS.
<script src="my-document-ready.js.html"></script>
<script>
  // 任何其他需要设置的全局变量
  $(document).ready(initPage); // or $(initPage);
</script>
  • 5. Не добавляйте поведение (встроенный JS) в HTML-файлы; это кошмар для отладки. Всегда используйте jQuery для привязки событий, и позже события будет легко отвязать.
<a id="myLink" href="../index.html" onclick="myEventHandler();">my link</a> <!-- BAD -->
$("#myLink").on("click", myEventHandler); // GOOD
  • 6. При необходимости используйте пользовательские пространства имен для событий. Это позволяет легко отвязать конкретные события на элементе DOM, не затрагивая другие события на этом элементе.
$("#myLink").on("click.mySpecialClick", myEventHandler); // GOOD
// 后面会很容易的解绑这个特定的点击事件
$("#myLink").unbind("click.mySpecialClick");

Ajax

  • 1. Избегайте использования.getJSON()и.get(), используйте только$.ajax(), первые два внутренне используют последний.
  • 2. Неhttpsиспользовать на веб-сайтахhttpзапросы. Предпочитайте протокол-относительные URL (удалите http/https из URL).
  • 3. Не помещайте параметры запроса в URL; вместо этого помещайте их в объект data.
// 不可读
$.ajax({
    url: "something.php?param1=test1&param2=test2",
    ....
});

// 可读
$.ajax({
    url: "something.php",
    data: { param1: test1, param2: test2 }
});
  • 4. Явно задавайте тип данных,dataTypeчтобы было легко понять, с какими данными вы сейчас работаете.
  • 5. При привязке событий к DOM-элементам, загруженным через Ajax, старайтесь использовать делегирование событий. Преимущество делегирования событий в том, что элементы, добавленные в DOM позже через Ajax, также могут реагировать на события.
$("#parent-container").on("click", "a", delegatedClickHandlerForAjax);
  • 6. Используйте Promises.
$.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: {},         // 请求参数对象
  dataType: "json", // 设置数据类型
  jsonp: "callback",// 只在操作JSONP时设置此项
  statusCode: {     // 针对特定错误码的回调处理函数
    404: handler404,
    500: handler500
  }
});
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);

Эффекты и анимации

1. Используйте единообразный подход для реализации анимаций.

2. Не злоупотребляйте анимационными эффектами, если только это не делается ради пользовательского опыта.

  • Старайтесь использовать простые методы show/hide/toggle/slideUp/slideDown для отображения и скрытия элементов.
  • Старайтесь использовать предопределенные длительности анимации:slow,fastили400

Плагины

  • 1. Всегда выбирайте плагины, которые хорошо поддерживаются, хорошо документированы, хорошо протестированы и имеют поддержку сообщества.
  • 2. Внимательно проверяйте совместимость плагина с используемой вами версией jQuery.
  • 3. Любые повторно используемые/универсальные компоненты следует выносить в плагины jQuery.

Метод цепочек

  • 1. Старайтесь использовать цепочки вместо кэширования переменных или многократного вызова методов селектора.
$("#myDiv").addClass("error").show();
  • 2. Когда цепочка превышает три вызова или становится сложной из-за привязки событий, используйте переносы строк и отступы, чтобы код оставался читаемым.
$("#myLink")
  .addClass("bold")
  .on("click", myClickHandler)
  .on("mouseover", myMouseOverHandler)
  .show();
  • 3. Для более длинных цепочек допустимо кэшировать промежуточный объект в переменной.

Другие принципы

  • 1. По возможности используйте объектные литералы для параметров.
$myLink.attr("href", "#").attr("title", "my link").attr("rel", "external"); // BAD
// GOOD
$myList.attr({
    href: "#",
    title: "my link",
    rel: "external"
});
  • 2. Не смешивайте CSS с jQuery.
$("#mydiv").css({'color':red, 'font-weight':'bold'}); // BAD

.error { color: red; font-weight: bold; } /* GOOD */
$("#mydiv").addClass("error"); // GOOD
  • 3. Не используйте устаревшие методы.
  • 4. При необходимости используйте нативные методы JS.
$("#myId"); // 还是慢了些
document.getElementById("myId");

Связанные ресурсы