25 советов по улучшению вашего кода jQuery

Original author: Jon Hobbs-Smith
  • Translation
Это перевод статьи, написанной Jon Hobbs-Smith. Я счел ее довольно интересной и решил выложить в своем блоге, а также поделиться им с хабрапользователями, также как и я заинтересованными в библиотеке jQuery. Перед тем как начать хочу отметить, что написана она (как и переведена) далеко не экспертом в jQuery, поэтому если вы найдете в ней ошибку, пожалуйста, сообщите. Итак, начнем.

1. Загружайте библиотеку с Google Code

На Google Code хранится несколько популярных Javascript библиотек, в том числе и jQuery, при этом есть несколько способов их подключения к вашему сайту. Надо сказать, что подгружаются они довольно быстро, к тому же если пользователь до этого посещал сайт, где библиотека подгружается таким же образом как и у вас с Google, то файл вообще загрузиться с кеша.

Подгрузить библиотеку можно через специально предусмотренный для этого API:




Либо напрямую:



Подробнее о способах подключения вы можете прочитать здесь.

2. Используйте шпаргалки

И не только для jQuery. В сети сейчас можно найти довольно большое количество удобных шпаргалок по многим языкам и библиотекам формата А4, так что ее можно к примеру распечатать и повесить на стенку рядом с компьютером.

Вот ссылки на пару таких:
http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/

Кроме того, мы обсуждали шпаргалки в одном из ранних постов.

3. Совмещайте и сжимайте ваши скрипты

Наверное, это один из главных советов по Javascript. Особенно это относиться к проектам, использующим большое количество плагинов. Большинство браузеров не может загружать файлы скриптов одновременно, а последовательная загрузка значительно увеличивает общее время загрузки всей страницы. Поэтому рекомендуется собирать все файлы в один большой скрипт.

Не забывайте сжимать ваш код. Большинство плагинов уже минимизированы, в противном случае рекомендуется сделать это, тем более это займет у вас всего несколько секунд. Например, можно воспользоваться Packer от Dean Edwards.

4. Используйте Firebug

Если вы его еще не установили, вы просто должны это сделать. Помимо таких замечательных вещей, как просмотр http трафика и обнаружения проблем в CSS эта надстройка ведет отличный лог команд, который может помочь вам в обнаружении ошибок в ваших скриптах.

Здесь вы найдете подробное описание всех его возможностей.

Очень полезна «console.info», с помощью которой вы можете выводить сообщения и значения переменной на экран без использования алертов, а также «console.time», которая позволяет вам засекать время выполнения определенных участков кода. Все они довольно просты в использовании.

console.time('create list');

for (i = 0; i < 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}

console.timeEnd('create list');


В данном случае я умышленно написал заведомо неэффективный код. Далее мы увидим, как можно использовать таймер, чтобы показать эффективность внесения улучшений.

5. Кэшируйте ваши селекторы.

Селекторы в jQuery потрясающие. С их помощью очень просто выбирать элементы на странице, но если вы используете их очень интенсивно в своем скрипте, это может существенно замедлить работу страницы.

Если вы все время обращаетесь к одному и тому же селектору, то можете просто внести его в память и затем использовать сколько угодно, не боясь навредить быстродействию. Давайте посмотрим следующий код:

for (i = 0; i < 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}


Выполнение этого простого кода заняло 1066 миллисекунд на моем компьютере в FF3 (представьте, как долго он бы выполнялся в IE6!). Теперь выполним аналогичный код, но используем селектор только один раз:

var myList = $('.myList');

for (i = 0; i < 1000; i++) {
myList.append('This is list item ' + i);
}


И что вы думаете? Всего 224 миллисекунды, более чем в 4 раза быстрее, а ведь мы передвинули всего одну линию кода :-)

6. Сведите манипуляцию с DOM к минимуму.

Мы можем еще ускорит код из предыдущего совета, сведя к минимуму работу с DOM. Операции для работы с DOM, такие как .append(), .prepend(), .after() и .wrap() очень дорогое удовольствие и частое их использование может также увеличить время выполнения вашего кода.

Все что потребуется в нашем случае — это использовать конкатенацию строк для построения списка, а затем использовать единожды метод .html() и наш код станет заметно быстрее. Давайте посмотрим пример.

var myList = $('#myList');

for (i=0; i<1000; i++){
myList.append('This is list item ' + i);
}


На моем компьютере он выпольнялся 216 миллисекунд, всего 1/5 секунды, но если мы сначала построим список в виде строки, а затем используем HTML метод для вставки следующим образом:

var myList = $('.myList');
var myListItems = '';

for (i = 0; i < 1000; i++) {
myListItems += 'This is list item ' + i + '';
}

myList.html(myListItems);


То такой скрипт будет выполняться уже 185 миллисекунд, на 31 миллисекунду быстрее. Какая-никакая, но все же экономия времени, а в случае с более сложным кодом эффективность будет более ощутима.

7. Оборачивайте все в один элемент прежде чем работать с DOM

Я не могу объяснить, почему это так работает, но наверняка эксперты в jQuery дадут на это ответ.

Дело в следующем. В нашей последнем примере мы вставили 1000 элементов списка в один элемент неупорядоченного списка, используя метод .html(). Если бы мы сначала обернули их в тег UL перед вставкой, а затем уже сформированный список вставляли в другой тег, например DIV, то это было бы намного эффективнее и быстрее, чем вставлять 1000 элементов. Давайте посмотрим пример, чтобы все стало ясно…

var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
myListItems += '<li>This is list item ' + i + '</li>';
}

myListItems += '</ul>';
myList.html(myListItems);


Такой код выполняется всего 19 миллисекунд, почти в 50 раз быстрее нашего самого первого примера.

8. Используйте идентификаторы вместо классов

В jQuery селекторы по классу такие же удобные, как и селекторы по идентификатору, что сделало их не менее популярными. Но все же лучше выбирать элементы по ID, так как jQuery использует для этого родной для каждого браузера метод getElementByID, а не какие то свои методы. Давайте посмотрим пример.

Я буду использовать предыдущий пример, но немного доработаю его так, что у каждого элемента списка будет свой уникальный класс. Затем мы пробежимся по всему списку и обратимся к каждому элементу по классу.

// Создаем наш список
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
myListItems += '<li class="listItem' + i + '">This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Выбираем по разу каждый элемент списка
for (i = 0; i < 1000; i++) {
var selectedItem = $('.listItem' + i);
}


Как я и ожидал, это задание заметно подгрузило мой браузер. По итогу время выполнения кода составило 5066 миллисекунд (более 5 секунд). Затем я изменил код и задал каждому элементу списка свой идентификатор взамен класса, а затем обратился к каждому элементу по его ID.

// Создаем наш список
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
myListItems += '<li id="listItem' + i + '">This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Выбираем по разу каждый элемент списка
for (i = 0; i < 1000; i++) {
var selectedItem = $('#listItem' + i);
}


Этот код выполнялся всего 61 миллисекунду. Почти в 100 раз быстрее.

9. Задавайте контекст в селекторах

По умолчанию, когда вы используете любой селектор, например $('.myDiv'), будет проанализирована вся структура DOM в его поисках, что на больших страницах может быть довольно накладно.

В таких случаях не надо забывать, что при построении селектора может быть задан второй параметр:

jQuery(выражение, контекст)

Устанавливая параметр контекст, вы указываете в каком именно элементе искать необходимый элемент, тем самым jQuery не придется просматривать всю структуру DOM.

Для демонстрации этого возьмем первый блок кода из предыдущего примера. Он создает несортированный список с 1000 элементов, у каждого из которых свой класс. Далее пробегаясь по всему списку он обращается к каждому классу. Эта операция заняла порядка 5 секунд чтобы перебрать таким образом каждый элемент.

var selectedItem = $('#listItem' + i);

Затем был добавлен параметр контекста, который выполнял селектор только внутри ненумерованного списка:

var selectedItem = $('#listItem' + i, $('.myList'));

Выполнение этого кода заняло 3818 миллисекунд, что на 25% быстрее. А ведь мы опять же внесли всего небольшое изменение в код.

10. Используйте цепочки

Одна из наиболее примечательных особенностей в jQuery это возможность использовать цепочки методов. Так, в следующем примере мы поменяем класс у элемента.

$('myDiv').removeClass('off').addClass('on');

Не стоит забывать, что код прекрасно работает с переносами строки (ведь jQuery = JavaScript), а это позволяет сделать ваш код более опрятным и читабельным, например, как в следующем примере.

$('#mypanel')
.find('TABLE .firstCol')
.removeClass('.firstCol')
.css('background' : 'red')
.append('Эта ячейка теперь красная!');


Стоить отметь, что привычка использовать цепочку методов помогает вам сократить код в использовании селекторов.

Но это еще не все. А что если вы хотите применить ряд функций к элементу, но одна из них меняет внешний вид элемента, например, как в следующем коде…

$('#myTable').find('.firstColumn').css('background','red');

Мы выбрали таблицу, нашли в ней ячейки класса firstColumn и покрасили их в красный цвет.

А давайте теперь еще закрасим все ячейки класса lastColumn в синий? Потому как мы использовали метод find(), мы отфильтровали из набора все элементы, которые не имеют класса firstColumn, таким образом, нам нужно использовать этот селектор снова, чтобы выбрать нужные элементы таблицы и не сможем продолжить цепочку методов. К счастью в jQuery имеется метод end(), который позволяет вернуться к предыдущему набору элементов, как в следующем примере.

$('#myTable')
.find('.firstColumn')
.css('background','red')
.end()
.find('.lastColumn')
.css('background','blue');


Кроме того, написать свою функцию, которую можно использовать в цепочке это намного проще, чем вы думаете. Для этого достаточно в по итогу выполнения всех действий с элементом вернуть его.

$.fn.makeRed = function() {
return $(this).css('background', 'red');
}

$('#myTable').find('.firstColumn').makeRed().append('привет');


Не правда ли, все достаточно просто?

11. О методе animate()

Когда я только начал использовать jQuery мне очень нравились уже определенные методы анимации, такие как slideDown() и fadeIn(), с помощью которых просто и быстро можно было сделать потрясающие эффекты. В основе каждой из этих функций лежит метод animate(), который очень функциональный и так же очень легко используется.

slideDown: function(speed,callback){
return this.animate({height: "show"}, speed, callback);
},

fadeIn: function(speed, callback){
return this.animate({opacity: "show"}, speed, callback);
}


Метод animate() просто изменяет различные свойства CSS от одного значения к другому. Таким образом, вы можете изменять высоту, ширину, прозрачность, цвет фона, различные отступы и все остальное что только пожелаете.

Например, вот так можно легко анимировать ваше меню, изменяя высоту элемента до 100 пикселей при наведении мышки.

$('#myList li').mouseover(function() {
$(this).animate({"height": 100}, "slow");
});


В отличие от других функций jQuery, анимация автоматически становится в очередь на выполнение, т.е. если вы захотите запустить одну анимацию следом за другой, достаточно всего лишь дважды вызвать анимацию, без каких-либо колбэков. В примере высота начнет изменяться сразу как закончится изменение ширины.

$('#myBox').mouseover(function() {
$(this).animate({ "width": 200 }, "slow");
$(this).animate({"height": 200}, "slow");
});


Если же вы хотите, чтобы анимация выполнялась параллельно, просто поместите оба стиля в объект параметров вызова метода, например, как в следующем примере.

$('#myBox').mouseover(function() {
$(this).animate({ "width": 200, "height": 200 }, "slow");
});


Вы всегда можете анимировать свойства с числовыми значениями. Кроме того, вы можете скачать плагин, который поможет вам анимировать свойства, значения которых не являются числами, например таких как цвета шрифта или фона.

12. Делегирование событий

С помощью jQuery очень просто привязывать события к элементам DOM, это замечательно, но привязка большого количества событий нерационально. Делегирование событий позволяет с помощью привязки меньшего количества событий достичь желаемого результата во многих ситуациях. Посмотрим пример.

$('#myTable TD').click(function(){
$(this).css('background', 'red');
});


Простая функция по клику окрашивает ячейки таблицы в красный цвет. А теперь представьте, если у нас таблица из 10 колонок и 50 строк, получается мы привязываем событие к 500 элементам. А что если бы мы могли привязать событие к таблице, а затем по клику на таблице определяли, какую именно ячейку окрасить в красный цвет?

Это как раз и называется делегированием событий. Давайте посмотрим, как оно работает.

$('#myTable').click(function(e) {
var clicked = $(e.target);
clicked.css('background', 'red');
});


'e' содержит информацию о событии, включая объект, по которому был произведен щелчок мышкой. Все что от нас требуется, это определить, по какой именно ячейке кликнул пользователь.

Кроме этого, делегирование элементов имеет еще один плюс. Обычно, когда вы привязываете событие к каким-либо элементам, то оно привязывается именно к этим элементам и никаким более. Если вы в процессе работы страницы добавили новые элементы в DOM, которые также соответствуют селектору, то к ним обработчик применятся уже не будет. В случае использования делегирования вы можете добавлять сколько угодно элементов в DOM после привязки события и с ними не будет никаких проблем.

13. Используйте классы для хранения состояний

Это самый простой путь для хранения информации о блоке html кода. jQuery хороша для манипулирования элементами с помощью классов, таким образом, если вам необходимо хранить информацию о состоянии какого-либо элемента, почему бы не воспользоваться специальным классом для этой цели?

В следующем примере мы создадим выпадающее меню. По клику на слое класса button подменю (класс panel) будет выпадать через slideDown() если оно не показано или прятаться через slideUp() если оно наоборот открыто. Итак, начнем с HTML.

<div class="menuItem expanded">
<div class="button">
Нажми меня
</div>
<div class="panel">
<ul>
<li>Элемент меню 1</li>
<li> Элемент меню 2</li>
<li> Элемент меню 3</li>
</ul>
</div>
</div>


Очень просто! Теперь добавим специальный класс, который будет хранить состояние подменю. В итоге нам будет необходимо лишь написать обработчик клика по диву класса button, который будет прятать либо показывать наше подменю с помощью slideUp() и slideDown() соответственно.

$('.button').click(function() {

var menuItem = $(this).parent();
var panel = menuItem.find('.panel');

if (menuItem.hasClass("expanded")) {
menuItem.removeClass('expanded').addClass('collapsed');
panel.slideUp();
}
else if (menuItem.hasClass("collapsed")) {
menuItem.removeClass('collapsed').addClass('expanded');
panel.slideDown();
}
});


Это очень простой пример, но вы можете добавлять специальные классы для хранения любой необходимой информации о каком-либо фрагменте HTML кода.

Как правило, такой подход используется в простых случаях. В более сложных лучше обратиться к содержанию следующего совета.

14. Используйте также встроенный метод data() для хранения данных

По каким-то причинам функция, о которой пойдет речь ниже не очень хорошо документирована, но тем не менее в jQuery есть встроенный метод data(), который может быть использован для хранения информации вида ключ-значение для любого элемента DOM. Посмотрим пример его использования.

$('#myDiv').data('currentState', 'off');

Мы можем доработать пример из предыдущего совета. Будем использовать тот же HTML код, но для хранения информации воспользуемся методом data().

$('.button').click(function() {

var menuItem = $(this).parent();
var panel = menuItem.find('.panel');

if (menuItem.data('collapsed')) {
menuItem.data('collapsed', false);
panel.slideDown();
}
else {
menuItem.data('collapsed', true);
panel.slideUp();
}
});


Думаю, вы согласитесь, что такой будет лучше. Для более подробной информации о методах data() и removeData() вы можете посетить раздел документации jQuery.

15. Пишите свои селекторы

В jQuery имеется большое количество встроенных селекторов. Но что вы делаете, когда вам нужно выбрать элементы по какому-то признаку, для которого нет решений в jQuery?

Конечно, можно изначально назначить им классы и затем обращаться к этим элементам через него. Но это не так сложно создать свой собственный селектор.

Давайте посмотрим пример.

$.extend($.expr[':'], {
over100pixels: function(a) {
return $(a).height() > 100;
}
});

$('.box:over100pixels').click(function() {
alert('The element you clicked is over 100 pixels high');
});


Первый блок кода создает селектор, который выбирает все элементы, которые по высоте больше 100 пикселей. Второй блок используется для привязки обработчика клика по таким элементам. Можно развивать эту тему дальше, но я думаю, вы уже заметили насколько это мощный инструмент и с легкостью обнаружите большое количество других самописных селекторов на гугле.

16. Упрощайте HTML и модифицируйте его при загрузке

Заголовок достаточно многозначительный, но этот совет может улучшить внешний вид вашего кода, уменьшить вес и время загрузки, а также в какой то мере помочь вам с SEO. Давайте посмотрим следующий HTML код для примера.

<div class="fieldOuter">
<div class="inner">
<div class="field">Это поле номер 1</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span>Это сообщение об ошибке</span></div>
</div>
</div>
<div class="fieldOuter">
<div class="inner">
<div class="field"> Это поле номер 2</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span> Это сообщение об ошибке </span></div>
</div>
</div>


Это пример разметки формы, немного модифицированный для наглядности. Я уверен, вы согласитесь, что код выглядит не очень красиво, и при большом размере формы вы получите не менее неприятную страницу. Согласитесь, следующий код выглядит намного лучше.

<div class="field"> Это поле номер 1</div>
<div class="field"> Это поле номер 2</div>
<div class="field"> Это поле номер 3</div>
<div class="field"> Это поле номер 4</div>
<div class="field"> Это поле номер 5</div>


Все что теперь от вас требуется это с помощью jQuery вернуть повторяющиеся фрагменты кода на место.

$(document).ready(function() {
$('.field').before('<div class="fieldOuter"><div class="inner">');
$('.field').after('</div><div class="errorBar"><div class="icon">
<img src="icon.png" alt="icon" /></div><div class="message">
<span> Это сообщение об ошибке </span></div></div></div>');
});


Не всегда советуется поступать таким образом, потому как при загрузке страницы может быть заметно подгрузка фрагментов кода, но в некоторых случаях, когда у вас много повторяющегося HTML кода, этот совет поможет уменьшить вес вашей страницы, а также преимущества в SEO при уменьшении повторяющихся фрагментов очевидны.

17. Подгрузка контента ради скорости и SEO

Другой способ ускорить загрузку вашей страницы и сделать HTML более читабельным это подгружать целые фрагменты кода используя AJAX-запросы после завершения загрузки страницы. Пользователи в итоге получат то, что нужно, а поисковые роботы увидят лишь то, что вы хотите им показать.

Сделать это можно как в следующем примере…

$('#forms').load('content/headerForms.html', function() {
// Здесь подгружаем весь необходимый нам код
});


Думаю, здесь все и так понятно, особо останавливаться не будем.

Конечно, опять же не стоит использовать этот совет повсеместно. Следует понимать, что это создает дополнительную нагрузку на сервер, а также часть вашей страницы может быть недоступна какое-то время для пользователя. Но при правильном использовании это может служить хорошей техникой оптимизации.

18. Используйте функции jQuery

jQuery служит не только для создания крутых эффектов анимации. Разработчики встроили в библиотеку несколько действительно полезных методов, которые могут восполнить некоторые недостатки функционала JavaScript в целом.

http://docs.jquery.com/Utilities

В частности, некоторые браузеры неполноценно поддерживают функции для работы с массивами (IE7 например даже не поддерживает метод indexOf()). jQuery имеет методы для итерации, фильтрации, клонирования, слияния и удаления дубликатов из массивов.

Другая распространенная проблема это трудность с получением выбранного элемента в выпадающем списке. В обычном JavaScript вы не сможете получить элемент SELECT через getElementByID, получить его дочерние элементы как массив и пройтись по ним, определив, какой из них выбран а какой нет. jQuery с легкостью решает эту проблему…

$('#selectList').val();

Поэтому лучше потерять немного времени и порыться в документации jQuery на основном сайте, почитав о других малоизвестных, но очень полезных функциях.

19. Используйте noconflict при работе совместно с другими библиотеками

Большинство javascript библиотек используют символ $ в своих целях, что может вызвать ошибки при использовании более чем одного фреймворка на одной странице. К счастью эта проблема просто решается с помощью метода .noconflict(), как в следующем примере.

var $j = jQuery.noConflict();
$j('#myDiv').hide();


20. Как узнать, что рисунок загрузился

Это еще одна из тех проблем, которая недостаточно документирована, как того стоит, но тем не менее очень часто всплывает при построении фотогалерей, каруселей и т.д., и на самом деле решается довольно просто.

Все что потребуется это воспользоваться методом .load() для элемента IMG и колбэк функцией по завершению загрузки в нем. В следующем примере изменяется атрибут src в теге рисунка для загрузки нового изображения и привязывается простая функция загрузки.

$('#myImage').attr('src', 'image.jpg').load(function() {
alert('Изображение загружено');
});


Как вы поняли, алерт появится по окончанию загрузки рисунка.

21. Всегда используйте последнюю версию

jQuery постоянно улучшается, а ее создатель Джон Резиг (John Resig) все время ищет пути для повышения производительности библиотеки. В связи с этим рекомендуется постоянно следить за обновлениями фреймворка (стабильными версиями) и обновлять вашу рабочую версию.

22. Как проверить, что элемент существует

Нет надобности проверять, присутствует ли элемент на странице, прежде чем выполнять с ним какие-либо действия, потому как jQuery просто проигнорирует действия с несуществующим элементом DOM. Но в том случае, если вам действительно необходимо проверить, было ли что-то выбрано и в каком количестве, используйте свойство length.

if ($('#myDiv).length) {
// Ваш код
}


Просто и очевидно.

23. Добавляйте класс JS к тегу HTML

Этот трюк описывается в книге Карла Сведберга (Karl Swedberg).

Первым делом при загрузке jQuery добавьте класс JS к вашему тегу HTML.

$('HTML').addClass('JS');

Поскольку это произойдет только если поддержка JavaScript включена на стороне пользователя, вы можете по этой же причине добавить специальный CSS стиль…

.JS #myDiv{display:none;}

Таким образом вы можете скрыть содержимое страницы, если поддержка JavaScript включена и затем используя jQuery показать его, если это необходимо (это относится например к выпадающим панелям, которые отображаются по клику на них). Пользователь без JavaScript (а также поисковые роботы) просто увидит все содержимое.

24. Возвращайте «false» чтобы избежать действия по умолчанию

Это вполне очевидно, но для кого-то может быть и незнакомо. Если вы имеете привычку делать вот так…

Нажми меня!

…а затем привязываете какой-нибудь обработчик событий, как например этот…

$('popup').click(function(){
// какой-нибудь код
});


…то все будет замечательно до той поры, пока вы не будете работать с этим на длинной странице, на которой вы увидите, что при клике на ссылке с # вы попадете на верх вашей странички.

Все что требуется в этом случае, чтобы избежать действия по умолчанию это добавить «return false;» в ваш обработчик события, например вот так…

$('popup').click(function(){
// какой-нибудь код
return false;
});


25. Укороченная запись события ready

Маленький совет по укороченной записи $(document).ready, который поможет сэкономить пару символов, но все же.

Вместо этого…

$(document).ready(function (){
// ваш код
});


Можно написать…

$(function (){
// ваш код
});


Спасибо за внимание. Этот и другие посты по jQuery вы также можете найти в моем блоге, посвященном данной библиотеке. К тому же, всегда буду рад видеть вас среди своих фолловеров на Твиттере.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 78

    +3
    >11. О методе animate()
    жаль пропущено важное описание параметра easing

    >20. Как узнать, что рисунок загрузился
    Также можно узнать, что рисунок не загрузился (404/403 итд):
    .error(function() {})
      0
      А подскажите пожалуйста, у меня есть большая страница со множеством img, flash, напичкана javascript с асинхронным изменением этой странице в браузере, при открытии в IE висит (почти бесконечно) progressbar. Как можно получить список того, что не может IE загрузить?
        0
        ну это немного из другой темы вопрос, поскольку .error() сработает тогда, когда сервер ответит, что картинки нет или что он не может ее дать. т.е. ответ от сервера уже придет. долгий прогресс-бар означает, что сервер затягивает с ответом (либо долго грузится большое количество ресурсов).

        если бы я столкнулся с подобной проблемой, я бы в первую очередь проверил через firebug какие ресурсы грузятся дольше всего. если firebub ничего определенного не показал (проблема специфична для IE), определил происходит ли «затык» при первоначальное загрузке страницы, либо в момент «асинхронных изменений», т.е. первым делом отключил эти самые изменения. (еще можно вставить [script] $(document).ready(function() { alert(«DOM READY»); }); [/script] и посмотреть в какой момент появится alert (и появится ли вообще).

        1) если проблема в первоначальной загрузке — в строке статуса должно быть написано какой ресурс грузится. если не пишется — можно попробовать поэтапно отключать ресурсы (опираясь на время загрузки, показанное в firebug — сначала наиболее долгие). и соответственно, таким методом исключения нашел источник проблемы, а дальше все зависит от его типа.

        2) если проблема в асинхронности, все проще — у каждого запроса (в т.ч. .load() для картинок) есть возможность повесить callback, а значит отследить время начала и окончания загрузки, а также ее продолжительность. т.е. можно нарисовать на страницу таблицу открытых/закрытых соединений с сервером, где будет отчетливо виден ответ на Ваш вопрос.

        а вот насчет flash ничего не скажу, не нравится мне эта технология и я с ней почти не работал.
          0
          тут может помочь метод дихотомии:
          сначала удалить первую половину кода, если ошибка исчезнет, то проблема во второй половине кода, и наоборот. так можно постепенно локализовать проблему, когда нет других средств отладки.
        –12
        Интересно, меня одного раздражают заголовки вроде «N советов чтобы стать богатым и успешным»?
          +10
          за всех не отвечу, но меня не раздражают. К тому же советы очень даже дельные.
            0
            Не, советы ты полезные, просто сами названия такого духа отдают чем-то вроде сайтов для IT-домохозяек lifehacker.
              0
              IT-домохозяек?
                0
                Ну это когда советы по гаджетам и софту смешиваются с советами о том как правильно складывать рубашки.
                  –1
                  Это не говоря уже про очевидность вех этих советов.
            +1
            Меня часто раздражают.
            Обычно под таким заголовком размерщается сборная солянка из пунктов, связанных между собой максимум тем, что им номера идут по порядку.
            К тому же, это известный прием для увеличения привлекательности рекламы. Посему считаю подобные вещи насилием над мозгом :)
            +1
            Очень полезно, спасибо!

            п.5. мне мерещится, или это действительно не кэширование, нечто другое?

            бага перевода: неупорядоченный список → ненумерованный список
              +14
                +1
                Вот и я думаю что где то это уже было
                  +5
                  Пипец. Три дня переводил. Закрываю.
                    +2
                    Тем не менее, спасибо за труд.
                      0
                      а я пропустил. спасибо за повтор
                        0
                        Чтобы не пропускать я пользуюсь rss по нужным мне тегам.
                        habrahabr.ru/rss/blogs/jquery/fba9b0abc3d5cb9937462e94e1102751/
                          0
                          я подписан на 150 потоков, среди которых есть главная хабра. поэтому я не удивляюсь, что пропустил. пожалуй, подпишусь еще по тегам.
                            0
                            У меня не меньше потоков)
                            Главную хабра не добавляю, т.к. слишком много и большинство ненужное. Добавил штук пять потоков по нужным тегам. Так и инфы меньше и таргетированность больше)
                        0
                        А я бы на ту статью и не наткнулся.
                        Надо сделать в Хабре периодическое циклическое «всплывание» статей — для тех, кто проморгал :-)

                        Таки спасибо: половину советов я уже знал, но в половине нашёл полезные детали.
                        Успехов.
                      +4
                      сиравно афатру спасибо,
                      старую статью я пропустил
                        0
                        Да. Я тогда даже распечатал в коллекцию шпаргалок на стене. До сих пор вот висит. Очень удивился когда снова увидел такую статью. Подумал что это со мной что-от не то… :)
                        0
                        Неплохая статья, спасибо!
                          +2
                          Вот яразу читаю «1. Загружайте библиотеку с Google Code» — и я против. Это создает проблемы. У меня сайт изначально и работал на этих аякс либах с гугла. Но потом случается следующее. Гугловский репозиторий чего-то лег на минут 30, ну как бы и все. Теперь всякая страничка, а это почти все, которые юзали эту либу — подвисают. Вот вы скажите сами себе — вам такой геморой нужен? Если либа грузится с моей странички — я знаю что это у меня проблема и я сам могу хоть как-то повлиять на работоспособность. А с гуглом нет. Поэтому пришлось отказаться от этой мегаидеи. Подожду пока другие набью шишки и гугл приведет отзывчивость серваков в порядок.
                            0
                            Но статейку в мемориз )
                              +1
                              При всем уважении к труду переводчика, но он опоздал на полгода. А ведь всего-лишь 4-я страница блога jQuery…
                              0
                              У меня ситуация аналогичная.

                              Контент с сайта отдаётся через https. Поэтому подгружать контент с других сайтов будет идеологически не верно. :)
                              +2
                              Эти советы мало относятся к самой jQuery, а к javascript в целом. По этому название немного не соответствует содержанию.
                              Особо порадовал автор своей фразой: «Я не могу объяснить, почему это так работает, но наверняка эксперты в jQuery дадут на это ответ» =)
                                0
                                Меня уже смутил пункт №1. Если в новой версии уберут функции, использующиеся в вашем коде, то что вы будете делать? Загружать код хорошо, если проект один и есть возможность быстро реагировать на обновления. На практике же лучше грузить руками всё-таки
                                  +2
                                  В п.1 подгружается конкретная версия. Очень маловероятно, что файл версии 1.3.2 будет изменяться со временем.
                                  0
                                  В примера заметил, довольно часто используется
                                  menuItem.removeClass('collapsed').addClass('expanded');

                                  Так вот для того чтобы просто прятать и показывать элементы можно заюзать TOGGLE()
                                  довольно простая, но код позволяет немного уменьшить.
                                  В примерах ее практически никто не используют, а зря
                                    0
                                    Ее можно использовать, если мы хотим убирать/добавлять один и тот же класснейм. Касательно примера метод toggleClass не применим.
                                      0
                                      не, .toggle() просто прячет/показывает, а не тугглит класс
                                    0
                                    12 — Делегирование уже давным-давно умеет делать сама jQuery через метод live. Но народ всё пишет и пишет свои решения, а потом ещё и статьи по ним…
                                      0
                                      live по ощущениям очень тяжелая. Если не ошибаюсь, биндер срабатывает на любые изменения DOM? На сложный селектор лучше даже не пытаться вешать, люди с ие7 и меньше устанут ждать.
                                        0
                                        У меня как раз наоборот ощущения — после перехода на live всё стало глаже работать. Но оно не для сложных селекторов, да. На несколько сложных элементов лучше вешать индивидуальные обработчики. А вот если на странице десяток-другой ячеек таблицы, которые должны как-то реагировать на мышь — live самое то.
                                          0
                                          не понимаю, зачем использовать два разных алгоритма для «десятка-другого» ячеек и для «тысячи-другой», если мы жертвуем универсальностью, и при этом в обоих случаях делегирование работает быстрее.
                                            0
                                            А вам простите что важнее — универсальность или оптимизация? Насколько я понял, весь этот топик об оптимизации. Если вы применяете различные решения задачи в зависимости от условий — это признак того, что вы хороший программист, а не просто кодер.
                                              0
                                              так в том то и дело, что мы жертвуем универсальностью, ничего взамен не получая (забыл это написать).

                                              у меня, к сожалению, так и не дошли руки (хотя давно чешутся) посмотреть как в jquery реализован live, но я подозреваю, что он вешается на изменения DOM. если это так, то такой вариант как минимум в разы медленее делегирования.
                                                0
                                                стоп, ничего я не забыл.
                                                написано же «в обоих случаях делегирование работает быстрее.»
                                                  0
                                                  Насчет live отпишусь позже, мне сходу не очевидно, как он работает.
                                          0
                                          Дата написания оригинальной статьии — 14 Dec 2008, тогда еще не было 1.3 версии.
                                            0
                                            да. только в новых версиях. но не забываем что в новых версиях есть баги которые не дают многим воспользоваться этими новыми версиями

                                            вот например jQuery('#'+objectId+'>param[name=flashvars]').val() не будет работать в новой версии, хотя прекрасно работает в v1.2.6
                                              0
                                              Да! И еще попроще пример: jQuery("#div #subdiv") не выбирает. Нужно менять на jQuery("#div").find("#subdiv").

                                              Не спрашивайте меня, зачем так делать… мне очень нравится плагин facebox, но он клонирует кусок DOM'a, когда создает лайтбокс-окошко… а это нужно чтобы разместить в клонированном окошке формочку, которую можно аяксом отправить
                                                0
                                                P.S. а в 1.2.6 выбирал как надо :)
                                            0
                                            24 — можно сделать лучше

                                              +1
                                              упс, извините, сорвалось… :)

                                              $('popup').click(function(event){
                                              // какой-нибудь код
                                              event.preventDefault();
                                              });
                                                +2
                                                простите, но Вы не правы.
                                                preventDefault() и return false; — это разные вещи, потому что return false; помимо отмены действия отменят и bubble-эффект.

                                                поэтому, верным будет код:

                                                $(«popup»).click(function(e) {
                                                // code
                                                e.preventDefault();
                                                e.stopPropagation();
                                                });

                                                что, согласитесь, не «лучше», чем return false;
                                                  0
                                                  вообще да, не обратил внимания, спасибо!
                                                  попался бы как-нибудь случайно — с ума бы сошел не зная этого :)
                                                    0
                                                    совсем не лучше, потому что в ие эти методы не работают.
                                                    0
                                                    А чем лучше то?
                                                      0
                                                      тем, что можно разделить отмену дефолт ивента и всплывание ивента же
                                                      return false как уже упоминалось выше делает и то и то одновременно, что не всегда нужно/удобно
                                                        0
                                                        а можно пример?
                                                          0
                                                          пример чего? :)

                                                          дефолт ивент — например сабмит формы, или переход по адресу на клик по ссылке — отменяеца так: e.preventDefault();

                                                          всплывание ивента — например если несколько элементов лежат друг над другом то клик может выстрелить на каждом из них — отменяеца с помощью e.stopPropagation();

                                                          return false делает и то и то одновременно
                                                    0
                                                    Да ладно, сам Резиг в своей книге Pro Javascript Techniques использует такой способ. Native & unobtrusive javascript: )
                                                      0
                                                      Понятно что чуток быстрее — без вызова обёртки, ну так… в качестве понта и для красоты :) хехе
                                                      просто есть и такой вариант
                                                    –4
                                                    1. Старайтесь не использовать jQuery — вот лучший совет, имхо.

                                                    Совет, про подключение с Гугла — бред. С нашего сервера файлы грузятся быстрее чем с Гугла, тем более в России. Также набили шишки на подключении с dev.jquery.com, он периодически падает дней так на 5, причем падает, не отвечая на соединения и подвешивая загрузку страницы…
                                                      0
                                                      там плюшка не в скорости загрузки, а в отсутствии ее необходимости, для тех, у кого файл скеширован (с другого сайта).
                                                      хотя я тоже предпочитаю делать локальную копию.
                                                        0
                                                        А кто мешает настроить кеширование статики на вашем сервере?
                                                          0
                                                          И не в этом суть плюшки :)

                                                          Если человек побывал на любом другом сайте, использующем jQuery, и подгружающем эту библиотеку от гугла (таких сайтов много, вероятность велика), то при заходе на ваш сайт он не будет подгружать ее снова.
                                                            0
                                                            Понял :)

                                                            Но реально, риски от перегрузки стороннего сервера (и белого экрана в ИЕ соотвественно) слишком велики.
                                                        0
                                                        Многотысячная аудитория пользователей jQuery нубы и ничего не понимают? Обоснуйте пожалуйста тезис насчет нерациональности этой библиотеки.
                                                          0
                                                          Многотысячная аудитория обменивает качество сайта на скорость написания скрипта (или что чаще, скорость скачивания и прикручивания плагина = пара минут).

                                                          Зачастую использование jQuery+плагинов необосновано, можно ради пары разворачивающихся меню и ручками написать скрипт, кроме того, на очень многих сайтах скрипты включаются в секции head (хотя в этом нет необходимости), также при этом не используется gzip, что вызывает необходимость загрузки 75 или 120 (если не minified версия) Кб только основного скрипта. В сочетании с размещением тега script в заголове страницы, это радикально замедляет загрузку сайта. Я считаю, на среднестатистическом информационном (или варезном, прости господи :) ) сайте приоритетом является скорость загрузки и отображения страницы, а не наличие примитивных бесполезных эффектов и анимаций.

                                                          Кто тут нубы, думайте сами.
                                                            0
                                                            Зачастую использование jQuery+плагинов необосновано

                                                            В этом Вы правы.
                                                            Но в остальном слишком категоричны и предвзяты.
                                                              0
                                                              а вы считаете, что jQuery — это для «примитивных бесполезных эффектов и анимаций»?
                                                                0
                                                                Ну это проблема не тех, кто «написал» плохую библиотеку. Это проблема использующих.

                                                                В любом случае при написании клиентской части кода вам придется создавать небольшую библиотеку часто используемых кроссбраузерных функций. Так почему бы не использовать для этих решений jQuery. Она написана людьми не глупыми. Чрезвычайная универсальность — это да, не поспоришь. Но если вас смущает размер библиотеки 19Кб, то можно сделать свою minified сборку. К примеру, не нужна вам анимация средствами JS — значит выкидываем все функции animate. Думаю, похужевшая jQuery будет весить 10-12 Кб.
                                                            0
                                                            > Особенно это относиться к проектам
                                                            Господи, ну сколько можно то?

                                                            А статья отличная, только я не любитель jQ.
                                                              0
                                                              Подскажите пожалуйста, у кого-нибудь меняется линк в адресной строке браузера при переключении по табам jQuery UI: jqueryui.com/demos/tabs/? Просто блин недавно менялся, а теперь перестал, что за фигня?
                                                                –1
                                                                Если не заменять угловые скобки («>» и «<») на их соответствующие HTML entities, то тогда Хабр начинает выкусывать их вместе с теми тегами HTML, которые угловыми скобками обрамлены.

                                                                В пункте 24 и, вероятно, в пункте 6 было больше HTML изначально, нежели сейчас видно.
                                                                  +1
                                                                  Шпоры в статье старые, уже давно для 1.3 сделали:
                                                                  acodingfool.typepad.com/blog/jquery-13-cheat-sheet.html
                                                                    0
                                                                    пункт 20 в таком виде не будет работать в опере, надо сначала повесить событие, а уже потом присваивать src.
                                                                      +1
                                                                      Хочу возвразить по поводу контекста (пункт 9)
                                                                      когда задаешь контекст $(".myElement",$(".myContect")) то это ничего не даст в плане производительности потому что $(".myContect") выполнится в контексте документа прироста не будет даже если контекстом будет $("#myContect").
                                                                      отвечаю сразу на несколько появившихся вопросов.
                                                                      1 Как надо делать? вот так
                                                                      $(".myElement",document.getElementById(«myContect»))
                                                                      2 Нет, document.getElementById(«myContect») и $("#myContect") не но и тоже. второй вариант это конечно же обертка к первому но перед тем как он выполнится сначала пройдет проверка регуляркой выделение селектора поиск в кеше, только потом будет выполнет поиск самого элемента, а потом он еще будет обернут в объект jQuery
                                                                      3 Да, в прошлом пункте я помалодушничал. если браузер поддерживает метод document.querySelect(All) то будет быстрее немного. это естественно не касается ИЕ 6 и 7 (насчет 7 не уверен)
                                                                        0
                                                                        в 9-м пункте скорее всего имеется ввиду
                                                                        не #listItem
                                                                        а .listItem
                                                                          0
                                                                          я ж говорю всеравно по идишке выбирать или по классу, если передавать туда чтолибо кроме html-ноды то оно все проходит полный цикл от разбора регуляркой до выборки из DOM.
                                                                          0
                                                                          По части пункта 21 не согласен. Предпочитаю немного подождать. Использовать свежий продукт не всегда полезно для здоровья и нервов.
                                                                            +1
                                                                            я могу сказать только одно. вы не понимаете смысла сводобного ПО
                                                                            да именно в том и дело что надо скачть свежую версию найти 1-2 косяка в функционале который использует ваш проект и запостить баг репорт а не ждать пока это сделают другие.
                                                                            0
                                                                            то файл вообще загрузиться с кеша.


                                                                            Уважаемые некоторые авторы Хабра. Может быть стоит запомнить простую проверку:
                                                                            — файл что сделает? Загрузится.

                                                                            Only users with full accounts can post comments. Log in, please.