Пользователь
0,0
рейтинг
18 февраля 2009 в 02:24

Разработка → Закрепляем jQuery — 25 отличных советов перевод

Перевод отличной статейки. Думаю, будет полезна как новичкам, которые только приступили к использованию jQuery, так и тем, кто уже какое-то время с ним работает. А кого-то, возможно, заставит глянуть эту чудесную библиотечку. Многие советы имеют отношение не только к jQuery, но и к JavaScript в целом. Лично для меня была весьма и весьма познавательной, посему и захотелось донести это «до масс». Перевод не дословный, но передающий смысл и максимально адаптированный к русскому языку.

Далее все написано от имени автора оригинальной статьи.

Введение


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

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

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

Содержание


  1. Загружайте фреймворк с Google Code
  2. Используйте «шпаргалку» (cheat sheet)
  3. Соединяйте все ваши скрипты и уменьшайте размер файла
  4. Используйте возможности Firebug для ведения логов
  5. Минимизируйте операции выборки в пользу кэширования
  6. Сводите манипуляции с DOM-деревом к минимуму
  7. Оборачивайте все в единый элемент, когда речь идет о любой вставке в DOM
  8. Используйте «id» вместо классов, где это возможно
  9. Задайте контекст своим селекторам
  10. Используйте последовательности вызовов методов с умом
  11. Научитесь правильно использовать анимацию
  12. Научитесь назначать и делегировать события
  13. Используйте классы для сохранения состояния
  14. Еще лучше — используйте встроенный в jQuery метод data() для сохранения состояния
  15. Пишите собственные селекторы
  16. Подготавливайте HTML и модифицируйте его, когда страница загружена
  17. Используйте «отложенную загрузку» (lazy loading) для определенного контента для выигрыша в общей скорости и преимуществ для SEO
  18. Используйте служебные функции jQuery
  19. Используйте «noconflict» для переименования глобального объекта «jquery», когда используете его с другими фреймворками
  20. Как узнать что картинки загружены?
  21. Всегда используйте последнюю версию
  22. Как проверить, что элемент существует?
  23. Добавляйте класс «JS» в элемент «html»
  24. Возвращайте «false» для отмены поведения по-умолчанию
  25. Короткая запись для события готовности документа



1. Загружайте фреймворк с Google Code


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

Это имеет немаловажное значение. Как много сайтов выдают идентичные копии jQuery, которые не кэшируются? Это очень просто сделать...


<script src="http://www.google.com/jsapi"></script>  
<script type="text/javascript">  
  
    // Загружаем jQuery  
    google.load("jquery", "1.2.6");  
  
    google.setOnLoadCallback(function() {  
        // Здесь, для разнообразия, можно даже написать какой-то код.
    });  
         
</script>

Или можно просто включить прямую ссылку, вроде этой...



Подробные инструкции здесь.

2. Используйте «шпаргалку» (cheat sheet)


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

http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/

3. Соединяйте все ваши скрипты и уменьшайте размер файла


Ну хорошо, это еще один совет в целом по JavaScript. Но любой большой проект, который вовсю использует jQuery, возможно использует множество плагинов (сайт автора использует localScroll, lightbox и preload), так что этот совет тут весьма кстати.

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

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

4. Используйте возможности Firebug для ведения логов


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

Здесь полное описание.

Мои любимые «фичи» — «console.info», которая позволяет выводить сообщения и переменные сразу на экран без использования alert-окошек, и «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('Это элемент списка № ' + i);  
}


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

var myList = $('.myList');  
  
for (i = 0; i < 1000; i++) {  
    myList.append('Это элемент списка № ' + i);  
}


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

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


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

Все, что нам нужно, это использовать соединение строк, чтобы построить список и затем всего-лишь одной функцией вроде .html() быстренько добавить элемент в наш маркированный список. Посмотрим пример:


var myList = $('#myList');  
  
for (i=0; i<1000; i++){  
    myList.append('Это элемент списка № ' + i);  
}  


У меня это заняло 216 миллисекунд, что чуть больше, чем 1/5 доля секунды, но если мы построим элементы списка в виде строк и затем используем метод .html() для вставки, вроде этого...

var myList = $('.myList');
var myListItems = '';
  
for (i = 0; i < 1000; i++) {  
    myListItems += '<li>Это элемент списка № ' + i + '</li>';  
}  
  
myList.html(myListItems);


Это занимает 185 миллисекунд, что не намного быстрее, но как-никак 31 миллисекундами меньше.

7. Оборачивайте все в единый элемент, когда речь идет о любой вставке в DOM


Окей, даже не спрашивайте меня, почему это работает (я уверен, что это сможет объяснить кто-нибудь поопытнее).

В нашем последнем примере мы вставили 1000 элементов списка в маркированный список, используя метод .html().
Если бы мы поместили их в тег «ul» до вставки и поместили бы готовый «ul» в другой тег (div), тогда мы бы успешно вставили только 1 тег вместо 1000, что, по всей видимости должно дать эффект. Вот как-то так...


var myList = $('.myList');  
var myListItems = '<ul>';  
  
for (i = 0; i < 1000; i++) {  
    myListItems += '<li>Это элемент списка № ' + i + '</li>';  
}  
  
myListItems += '</ul>';  
myList.html(myListItems);  


В этот раз, «на все про все» ушло не иначе, как 19 миллисекунд, что крайне существенное улучшение, производительность возросла более, чем в 50 раз по сравнению с первым примером.

8. Используйте «id» вместо классов, где это возможно


jQuery делает выборку DOM-элементов по классам такой же простой, какой в JavaScript является выборка элементов по «id», в результате чего многие используют классы куда более широко, нежели раньше. Однако, все еще гораздо лучше выбирать элементы по «id», так как jQuery использует для этого стандартный метод любого браузера (getElementById) и не проводит никаких дополнительных манипуляций с DOM, что позволяет достичь хорошей производительности. Насколько хорошей? Давайте проверим.

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


// Создаем список
var myList = $('.myList');  
var myListItems = '<ul>';  
  
for (i = 0; i < 1000; i++) {  
    myListItems += '<li class="listItem' + i + '">Это элемент списка №</li>';  
}  
  
myListItems += '</ul>';  
myList.html(myListItems);  
  
// Выбираем каждый элемент в цикле
for (i = 0; i < 1000; i++) {  
    var selectedItem = $('.listItem' + i);  
}


В точности как я и предполагал, браузер неслабо подвис и закончил выполнение только через 5066 миллисекунд (более 5 секунд). Так что я модифицировал код, дав каждому элементу id вместо класса и затем также выбрал каждый в цикле, но уже по 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 принимает второй параметр, когда производит выборка.


<i>jQuery(expression, context)</i>


Передавая контекст в селектор, вы сообщаете ему элемент, с которого нужно начинать искать. Таким образом, необходимость обращения ко всему DOM-документу отпадает.

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


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


Затем, я добавил контекст, чтобы jQuery использовал селектор только в пределах маркированного списка. Вроде этого:

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


Это заняло 3818 миллисекунд, что само по себе все еще адски медленно, но это уже более, чем 25%-й прирост в скорости при минимальной модификации селектора.



10. Используйте последовательности вызовов методов


Одна из самых клевых фишек в jQuery — это возможность выстраивать последовательности вызовов методов. Например, если вы хотите поменять класс элемента:

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


Скорее всего, вы выучили это в первые же 5 минут использования jQuery, но это еще не все. Во-первых, это прекрасно работает с переносами строк (поскольку jQuery — это все же JavaScript), что означает, что вы можете писать красивый код вроде этого:

$('#mypanel')  
    .find('TABLE .firstCol')  
    .removeClass('.firstCol')  
    .css('background' : 'red')  
    .append('<span>Теперь эта ячейка красная</span>');


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

Но и это еще не все. Скажем, вы хотите выполнить несколько функций на элементе, но одно из первых же применений изменило элемент каким-либо образом, например:


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


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

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


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


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

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

$('#myTable').find('.firstColumn').makeRed().append('hello');  


Просто, правда?

11. Научитесь правильно использовать анимацию


Когда я только начал использовать jQuery, я был в восторге от простоты в использовании встроенной анимации вроде slideDown() и fadeIn() для получения клевых эффектов. Очень просто пойти чуть дальше, поскольку метод jQuery animate() очень прост для использования и одновременно очень крут. Фактически, если посмотреть на исходники jQuery, можно увидеть, что все эти методы — эдакие мини-абстракции, частные случаи использования функции 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 px в высоту при наведении мышкой:


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


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

$('#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, сколько вам заблагорассудится и обработчик событий будет нормально работать и с ними.


На момент написания статьи, автором использовалась версия 1.2.6, однако начиная с версии 1.3, в jQuery появился новый функционал, адресованный как раз проблеме переназначения событий — jQuery Event/live.

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


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

А вот и пример. Мы хотим создать разворачивающееся меню. Когда мы нажимаем на кнопку, мы хотим, чтобы панель появилась со slideDown(), если она закрыта и наоборот — исчезла со slideUp(), если открыта. Начнем с HTML:


<div class="menuItem expanded">  
    <div class="button">  
        click me  
    </div>  
    <div class="panel">  
        <ul>  
            <li>Пункт меню 1</li>  
            <li>Пункт меню 2</li>  
            <li>Пункт меню 3</li>  
        </ul>  
    </div>  
</div>  


Очень просто! Мы просто добавили дополнительный класс к элементу-обертке (div), который не имеет иной роли, кроме как сообщить нам состояние элемента. Так что, все что нам нужно — обработчик события «onclick», который производит 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. Совсем круто — используйте встроенный в jQuery метод data() для сохранения состояния


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

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


Мы можем улучшить пример из прошлого совета. Мы используем тот же HTML (кроме класса «expanded») и используем функцию 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 internals.

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


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

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

До сих пор, лучший способ продемонстрировать это — пример:


$.extend($.expr[':'], {  
    over100pixels: function(a) {  
        return $(a).height() > 100;  
    }  
});  
  
$('.box:over100pixels').click(function() {  
    alert('Элемент, который вы потревожили своим кликом, в высоту более 100 пикселов');
});  


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

Я не буду здесь еще более детально рассматривать все это, но вы уже можете представить, насколько суперкрут такой инструмент и если порыскать в Гугле на тему «custom jquery selector», можно найти много интересного.


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>  


Это пример того, какой может быть разметка формы, слегка модифицированная, чтобы проиллюстрировать наши задачи. Я уверен, вы согласитесь, что этот код ужасен и если у вас большая форма — вы закончите с неприлично длинной и, мягко говоря, некрасивой страничкой. Куда лучше было бы иметь что-то вроде этого в HTML:

<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, чтобы вернуть тот самый некрасивый HTML. Смотрим:

$(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-я, это может существенно снизить вес страницы и вообще оптимизировать ее и привести в порядок.



17. Используйте «отложенную загрузку» (lazy loading) для определенного контента для выигрыша в общей скорости и преимуществ для SEO


Еще один способ увеличить скорость загрузки страницы и очистить HTML, который просматривают поисковые роботы — это использовать так называемый «lazy loading» или говоря по-чукотски по-простому — отложенную загрузку целых частей, используя AJAX-запрос после того, как страница уже загружена. Пользователи смогут немедленно увидеть информацию, а поисковики — им и подавно, только информация и нужна.

Мы использовали эту технику на нашем собственном сайте. Те фиолетовые кнопочки наверху страницы подгружают 3 формы, направления и карту Google, которые увеличили бы изначальный вес страницы вдвое. Так что мы просто поместили весь HTML в статичную страницу и использовали функцию load(), чтобы загрузить все это уже после полной загрузки документа. Делается вот так:


$('#forms').load('content/headerForms.html', function() {  
    // Этот код выполнится после загрузки статичного контента
    // Сюда помещаем всякого рода обработчики и т. д.
});  


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

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


jQuery — это не только ослепительные эффекты. Создатель наделил его некоторыми действительно полезными методами, которые могут восполнить пробелы в репертуаре JavaScript:

jQuery utilities

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

К другим труднореализуемым вещам в JavaScript относится, к примеру, задача, где нужно получить выбранный элемент из выпадающего списка. В старом добром JavaScript нам пришлось бы получить элемент «select», используя getElementById, получить дочерние элементы как массив и «пробежаться» по ним в итерации, проверяя каждый, был он выбран или нет. jQuery упрощает подобные дела:


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


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

19. Используйте «noconflict» для переименования глобального объекта «jquery», когда используете его с другими фреймворками


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

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


20. Как узнать что картинки загружены?


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

Все, что нужно — использовать метод .load() на элементе «img» и вызвать в нем (методе) callback-функцию. Следующие примеры заменяют значение атрибута «src» у картинки для подгрузки новых изображений и присоединяют простую функцию загрузки:


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


Можете проверить, alert будет вызван, когда картинка загрузится.

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


jQuery постоянно развивается и John Resig, его создатель, день и ночь в поисках путей улучшения производительности.

jQuery сейчас (на момент написания статьи — прим. пер.) в версии 1.2.6, но Джон уже раскрыл, что он работает над новым движком выборки — Sizzle, который увеличит скорость выборки, к примеру, в Firefox, в 4 раза. Так что, чем свежее — тем лучше.


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


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

if ($('#myDiv).length) {  
    // your code  
}


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

23. Добавляйте класс «JS» в элемент «html»


Я узнал эту фишку от товарища Karl'а Swedberg'а, по чьим замечательным книгам я изучал jQuery.

Недавно на одну из моих предыдущих статей он оставил комментарий об этом приеме и суть в следующем…

В первую очередь, как только jQuery загрузится, мы используем его для добавления
класса «JS» к тегу «html»:


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


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

.JS #myDiv{display:none;}


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

Можете прочитать его полную статью
здесь.

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


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

<a href="#" class="popup">Нажми меня, злодей!</a>  


… а затем назначать обработчик события вот таким вот образом:

$('.popup').click(function(){  
    // Код запуска popup'а
});


… то возможно это будет нормально работать, но ровно до тех пор, пока страничка не станет длиннее, чем ожидалось изначально. В таком случае, вы увидите, как после каждого нажатия на ссылку, страничка «прыгает» в самое начало (знак #).

Все, что нужно — отменить стандартное поведение ссылки, впрочем, как и любого другого элемента. Для этого нужно добавить «return false;» в свой обработчик, например:


$('.popup').click(function(){  
    // Код запуска popup'а
    return false;  
});


25. Короткая запись для события готовности документа


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

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


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


можно сделать вот так:

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


На этом эпическая коллекция приемов в jQuery от товарища Jon Hobbs-Smith'а заканчивается. Надеюсь, вам удалось почерпнуть для себя что-нибудь новое.

Update. Спасибо хабраюзеру NemeZZiZZ за то, что справедливо обозвал «unordered list» маркированным списком (я перевел это как «неупорядоченный список», что, конечно, дословно, но определенно отдает чем-то чукотским).

Update 2. Спасибо хабраюзеру david_mz за указание на новые особенности jQuery, начиная с версии 1.3, которые касаются назначения и делегирования событий (см. п. 12).
Перевод: Jon Hobbs-Smith
Vasilio Ruzanni @VasilioRuzanni
карма
77,6
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (109)

  • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      Спасибо за замечание. Хотя в оригинале у автора и стоит значок равенства, я думаю, все-таки, стоит поправить.
  • +1
    Действительно, отличные советы! Всё очень полезно и в одном месте.
  • +2
    Однозначно в копилку все, спасибо!
  • +2
    искал решение по JQuery, зашел на Хабр, а тут такая красота =)
  • +2
    Шикаррно.
    Распечатал cheat sheet, например.
    • 0
      javascripttoolbox.com/jquery/JQueryCheatSheet.xls
      еще я пользуюсь такой шпаргалкой уже длительноє время… информативно и удобно, на мой взгляд)
  • +1
    Спасибо… много интересного. в Избранное
  • +1
    Ни у кого нет распечатываемой шпаргалки для 1.3.1 версии?
    А советами уже давно пользуюсь, читал статью в оригинале.
  • +1
    Я, что-то не понял 25-й пункт: «сэкономить несколько символов, если использовать функцию»? Странно, мне кажется что если «не использовать что-то» то можно сэкономить на этом!..

    Да и в пункт 21, я бы добавил такое маленькое дополнение «см. также AJAX-библиотеки в Google».
    • +1
      Теперь дошло! Подправьте 25-й пунктик, пожалуйста, на такое:
      «Маленький прием, который поможет сэкономить несколько символов, если использовать сокращение функции $(document).ready.»

      • 0
        Сенькс! Когда переводишь, иногда несколько выпадаешь из контекста. Сейчас использую ваш вариант.
    • 0
      Ну а ссылка на Google Code уже есть в 1-м же совете.
  • НЛО прилетело и опубликовало эту надпись здесь
  • +3
    Эммм… «неупорядоченный список»??? Вы хотели сказать «ненумерованный список» или «маркированный список»?
    • 0
      Ну, там суть именно в том, что неупорядоченный. Т.е. не отсортированный по какому-либо признаку. Суть, видимо, в том, чтобы проиллюстрировать, что мы «просто вставляем элементы», никак не заботясь о последовательности. Сам тоже отчасти думаю, что это лишнее определение, можно было бы назвать просто «список», к примеру.

      В оригинале звучит как «unordered» — сложно подобрать правильный перевод в этом контексте, посему перевел дословно.
      • +2
        тег OL — ordered list, нумерованный список
        тег UL — unordered list, ненумерованный список
        • 0
          Мда, пожалуй :))
  • +1
    спасибо.
  • +4
    Про .noconflict(): стоит упомянуть, что с момента употребления этой функции объект $ возвращается в первоначально определенное состояние. То есть, по-русски, если сначала вы загрузили Prototype, a потом jQuery, jQuery.noconflict() снова сделает объект $ прототиповской функцией. Это не всегда может быть удобно для дополнительного «навешивания» скриптов, полагающихся на jQuery в форме $. Посему (и не только поэтому), свои jQ-скрипты стоит писать следующим образом:
    // начинаем файл нашего скрипта
    (function($) // анонимная функция-обертка с параметром
    {
    $(".mystuff").do(things) // наши jQuery-выкрутасы, за состояние $ можно не бояться
    }
    )(jQuery) // и вот почему :)
    // заканчиваем файл нашего скрипта

    Первой и последней строчками мы оборачиваем наш скрипт в анонимную функцию, принимающую параметр $. В последней строке мы вызываем только что созданную функцию и в качестве этого параметра передаем объект jQuery. В итоге .noconflict() нам не страшен (его и можно, кстати, употребить в первой строчке нашего скрипта, перед объявлением функции). Заодно работа скрипта внутри анонимной функции, вызываемой немедленно после создания, не оставит после себя мусора в виде локальных переменных — если их объявлять с ключевым словом var, они исчезнут из памяти сразу после исчезновения контекста функции (то есть в простейших случаях сразу после окончания ее работы, в случаях замыканий при обработке событий — после снятия обработчиков событий). Практическая польза кажется небольшой и неочевидной, пока вы используете только jQuery, но стоит взяться за большой проект с несколькими библиотеками… сэкономите на Солпадеине, вобщем.
  • +6
    Еще момент: вчера всплывала статья про jQuery, хотел откомментить там, но хабр коммент сожрал.

    Итак: кэшируя jQ-объект в переменную, именуйте ее с помощью $ в начале. То есть:

    $a = $('a')


    «Лишний» байт на самом деле сугубо повысит читаемость/разбираемось вашего кода для сторонних программистов (или вы гарантируете, что через год поможете модифицировать скрипт?). Особенно важно в обработчиках событий:

    $('#myid').bind('click', function(){ // когда делаем обработчик события
    var $this = $(this) // оборачиваем DOM-объект, на котором всплыло событие, в jQuery
    })

    Не понадобится обертка вокруг this — всегда можно удалить одну строчку. Но лично у меня уже стало паттерном, руки сами набирают, пока голова думает над деталями обработки события.

    И еще. Бывает, глубоко в цепочке из многих .find() вдруг оказывается позарез нужна текущая jQuery-выборка в виде переменной. Понятное дело, не разорвав красивой цепочки, такую переменную не родишь ниоткуда. Заново повторять выборку ради своих действий тоже накладно. Для такого дела я когда-то написал простенький плагин: plugins.jquery.com/project/jquery_apply. Посреди цепочки можно вызвать .apply(function(){}), где внутри функции текущая jQuery-выборка доступна в форме this.
    • 0
      Дельный совет. Ну, на самом деле, автор и сообщает, что все нужно применять с умом ;)
      За плагин спасибо.
  • 0
    Концентрация полезной информации — огромная, сам узнал правда только про расширяемые селекторы, но читать было очень приятно, спасибо. Одно несогласие:

    23. Добавляйте класс «JS» в элемент «html»
    — здесь будет явная проблема при открытии страницы, вы увидите много контента, а потом(в момент когда произойдет .ready() ) он спрячется. То есть пользователь увидит мерцающие блоки. К слову — подобный прием используется на главной странице mail.yandex.ru для скрытия боковых панелей — смотрится фигово, здесь лучше даже на таких монстров не ровняться.

    зы: 24. return false; можно сократить до return !1;
    • 0
      Ну, 23 — это все же, как мне кажется, частный случай. Кому-то такое подходит, кому-то нет.

      А вот 24 — что-то мне подсказывает, что «ох, не стоит же этого делать». Мало ли что он там не так сделает. «false» надежно, да и, на мой взгляд, читабельнее.
      • 0
        ! — это логическая команда «отрицание», отрицание единицы по-булевски будет false, даже можно не проверять в других браузерах, все верно.
        • 0
          Ну, возможно. Про логическое отрицание я знаю, но вы же сами понимаете, реализации всегда неидеально. Впрочем, спорить не буду — надо проверить во всех браузерах, да и все.
    • 0
      23. Ну это смотря как сделать. Можно и css это всё выровнять. Например, как и на Я.Субботнике, когда Виталий Харисов рассказывал про CSS Framework. (теория (видео ч.1, видео ч.1) и практика (видео ч.1, видео ч.2)) Если у пользователя нет JS, то блок не скрываем. Вот простой пример:

      Если фнкция не сработала, то у элемента html нет класса JS и в css пишем просто:
      .block { display: block; }

      Если сработала функция и элементу html был задан клас JS, то в css стилях очень просто написать:
      .js .block { display: none; /*или visibility: hidden; */ }

      Ну и конечно не забываем про наследование стилей.

      А, вообще я больше склоняюсь к использованию id у элемента html. Изначально элементу html у меня выставляется свойство id="nojs" а уже потом JS-ом изменяется на id="js" И соответсветнно в css два стиля, для ситуации когда нет JS и когда JS есть.

      #js .block { display: none; }

      #nojs .block { display: block; }
      • +1
        вы видимо не поняли о чем речь — js срабатывает после того как уже загружен html, то есть рендеринг css будет на определенное время дольше, то что накидывается класс для body и пишутся исключения — и так ясно, проблема в том, что сначала срабатывает .block { display: block; }, а потом уже .js .block {display: none;}. Решение работает криво и через одно место, его нельзя рекомендовать.

        менять id у элемента DOM-дерева через js — еще более неправлиный трюк, id для того и создан, чтобы однозначно инициализировать конкретный элемент, а не через него управлять отображением css. Представляю как двое-трое участвуют в разработке и один навешивает id для придания какогой-либо динамики через js, а другой для своих дизайнерских нужд эти id переопределят. Фу короче :)
        • +1
          id для того и создан, чтобы однозначно инициализировать конкретный элемент, а не через него управлять отображением css

          Вы общались с Создателем?
          Или кто ещё вам запретил использовать ID для отображения CSS?

          Мне кажется, что техника #js .block — самое простое и эффективное решение проблемы обратной совместимости.

          Решение работает криво и через одно место, его нельзя рекомендовать.

          Что значит криво ичерез одно место?
          Оно работает и проблем с задержками в рендеринге нет.
          • 0
            ferrari достаточно четко описал возможные проблемы при изменении id элемента. Что мешает использовать селекторы .js .block и .nojs .block? Классы для того и существуют, чтобы управлять отображением элементов.
            • +1
              Т.е. вы утверждаете, что html#js нельзя использовать, а html.js можно?

              Вы не поверите, но ID тоже можно использовать для управления отображением элементов, и это, вроде как, никем не запрещено.
              • 0
                Я утверждаю, что нельзя скриптом менять html#nojs на html#js, о чем и говорил предыдущий оратор.
                • +2
                  Omg, а так можно:

                  JS:

                  document.documentElement.id = 'js';

                  CSS:

                  .block {…}
                  #js .block {…}


                  ?
                  • 0
                    Конечно. Но так вы лишаетесь стилей только для браузера без js, либо придется писать их в .block и переопределять в #js .block
                    • +1
                      Ну, естественно — сначала создаётся функционал простой, который так же просто описывается в CSS.
                      А потом его начинают JS-ить и пишут экстра-правила через #js.

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

                      Исключение — когда компонент в принципе JS'ный и не имеет никакого вида с отключённым JS. В это случае — он просто не выводится на экран, а правила для него пишутся просто так.

                      Так в чём проблема с этим подходом, не могли бы вы резюмировать?
                      • +1
                        К тому же указывать атрибут «class» для <html> не валидно.

                        Нету этого атрибута, например в «XHTML Strict 1.0»:
                        <!ELEMENT html (head, body)>
                        <!ATTLIST html
                          %i18n;
                          id          ID             #IMPLIED
                          xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
                          >
                        • НЛО прилетело и опубликовало эту надпись здесь
                    • +2
                      И вот ещё мелочь — в XHTML у элемента HTML нет атрибута class, есть только xmlns и id. Поэтому потенциально вы рискуете несовместимостью, но на практике наверное вряд ли.

                      Для кого-то это может иметь значение.
                      • 0
                        Я оперирую классами body.

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

                        А вообще я высказался только против изменения id элемента (не присвоения безымянному, а именно изменения).
                        • +1
                          На вопрос знатоков отвечает Вадим Макишвили:
                          • –1
                            Вы хотите меня убедить что это правильный подход?
                            Я считаю что нет, даже если так делают уважаемые люди. Представьте, что в 1712 году Петербург переименовали бы в Москву, а Москву в Петербург, а в начале нашего века переименовали бы обратно. То есть вместо статуса изменили бы идентификатор.
                            • 0
                              Вы правда видите что-то общее, между атрибутом ID и названием города? :-O
                              • +1
                                У них одна суть — однозначная идентификация объекта. В отличие от классов и статусов, которые могут меняться, что мы и видим в нашем примере: обычный документ приобретает статус документа с js, и это влияет на его представление.
                            • 0
                              Ну и, гм, указанное решение хорошо не только уважаемостью людей, его использующих, но и тем, где это используется — проекты Яндекса создаются в большой команде (был такой аргумент выше) и все нагрузочные вопросы внимательно тестируются.
                              • 0
                                Объясните тогда, чем плох вариант с классом (кроме того, что его не используют в Яндексе)?
                                • 0
                                  У элемента HTML нет атрибута class.
                                  Ну хоть убейся )
                                  • 0
                                    Я уже писал, что оперирую классами body. Сдавайтесь :)
                                    • 0
                                      Patria o Muerte!
                                      • 0
                                        Вадим, относись к жизни проще. Каждый вправе считать себя самым правым. Сторонние читатели уже поняли для себя какой метод лучше.
                                        • 0
                                          Да нет, я крепко сплю и аппетит хороший.
                                          Просто из спортивного интереса пытался понять точку зрения товарища )
                      • 0
                        Упс пока писал комментарий, вы уже ответили это :-)
  • +2
    Супер!!! Спасибо огромное.
  • +2
    Супер статья, я как раз начинаю изучать JQuery, очень помогает быстро въехать в тему, большое спасибо.
  • +2
    А зачем текст серым делать?

    Спасибо, полезный сборник.
    • 0
      Итак, зачем серый текст. Стандартные стили Хабра подходили не очень, так как нужно было выделить заголовки — здесь они играют чуть большую роль, чем обычно, поскольку озвучивают собственно советы. Кроме этого, я еще оставил выделенными кусочки кода. Как по мне, и думаю, многие согласятся, такое форматирование вполне себе очень читабельно.
      • 0
        Желание автора — закон, я лишь поинтересовался ;)
      • 0
        довольно фигово читабельно, честно говоря :)

        но за перевод всё равно огромное спасибо, статья — клад!
  • –2
    Кстати, первый совет используется в ZendX_JQuery :)
  • +1
    Спасибо за перевод, действительно очень много полезной информации. Но хотелось бы дать несколько поправок/уточнений/пожеланий:

    1. Загружайте фреймворк с Google Code

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

    3. Соединяйте все ваши скрипты и уменьшайте размер файла

    Рекомендуется использовать Packer. Однако сами авторы jQuery начиная с версии 1.3 перестали выкладывать packed-версию, потому что потери времени на распаковку packed-скрипта заметно превышают выигрыш от уменьшения размера, плюс имеют проблемы с совместимостью. Подробности тут: blog.jquery.com/2009/01/21/jquery-131-released/. Их рекомендация — JSMin + gzip.

    12. Научитесь назначать и делегировать события

    В статье описывается версия 1.2.6. Начиная с версии 1.3 в jQuery появился специальный механизм для этого: docs.jquery.com/Events/live

    • 0
      Спасибо за замечания. Полностью согласен. В любом же случае, при использовании надо еще и головой думать :)
      Насчет версии 1.3 — это да, действительно есть новый механизм и я думаю, можно будет его отдельно рассмотреть в отдельной статье (я уже даже встречал примеры с live в западных блогах, где все отлично описано).
      • +1
        Конкретно про live — я бы всё-таки попросил упомянуть в статье. Потому что это именно оно, а так народ, для которого это первый материал по сабжу, начнёт велосипеды изобретать.
        • 0
          Упомянуть стоит. Но, кстати, я тут подумал — а не разные ли все-таки это вещи? Цель, конечно, одна. Но суть в том, что в этой статье событие в итоге назначается один раз и уже в обработчике вся логика проверки дочерних элементов. В то время как live() занимается именно назначением событий, или не так? Я рассматриваю с точки зрения производительности.
          • 0
            Нет-нет, это как раз именно делегирование. Live именно цепляется один раз как глобальный обработчик, а потом при наступлении события смотрит, у кого оно произошло. Если селектор совпадает — вызывается соответствующий обработчик. То есть, один раз задав $('p').live('click', …), можно потом насоздавать сколько угодно параграфов, и все они будут отзываться на клик.

            Там по ссылке-то всё написано:)
            • 0
              Ну я прочитал, но в коде-то не лазил, поэтому незнаю подробностей. Т.е. правильно я тогда понимаю, что новых обработчиков не назначается никаким элементам, а просто отслеживаются элементы по селектору и вызывается _только_ существующий обработчик?
              • +1
                Да.
                • 0
                  Ок, всяко, спасибо за замечание. Как вы, наверняка, уже заметили, я внес поправки в статью и указал автора замечания.
      • НЛО прилетело и опубликовало эту надпись здесь
  • +4
    надо еще заметить что при такой google.load("jquery", "1.2.6") загрузке $(document).ready не будт работать
  • 0
    просьба сделать хабракат. А пока почитаю.
    • +2
      Куда уж «хабракатее». Считаю, что «содержание» всяко должна быть возможность прочитать до открытия статьи.
      • 0
        Достаточно само описание статьи показывать. По крайней мере, мне так кажется.
  • +1
    итак, статья имеет пару плохих советов.

    В совете 6 корректный код должен выглядеть так:

    var myList = $('.myList');
    var myListItems = [];
    for (i = 0; i < 1000; i++) {
    myListItems.push('Это элемент списка № ' + i + '');
    }
    myList.html(myListItems.join(''));

    В совете 24 правильно делать не так, а использовать e.preventDefault.

    $('#id').click(function(e)
    {
    e.preventDefault();
    // do actions
    });
    • 0
      Может быть, но за всем не уследишь. По поводу совета 24 согласен, а вот насчет 6 — неуверен, надо проверять по производительности.
      • +2
        Проверьте :)

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

        Кстати, и запись так удобнее. Пример:

        var html = [];
        // тут много формирования HTML
        html = html.concat(['В этой эпохе зафиксировано ', c, ' неликвидов.']);
        // тут много формирования HTML
        $('#info').html(html.join(''));
    • +1
      анписал автору статьи, на всякий :)
      • 0
        Отпишитесь, если ответит :)
  • 0
    {jxe gjltkbnmcz c [f,hjj,otcndjv cdjtq cnfnmt j crjhjcnb ctktrnjhjd b ghfdbkmyjv b[ yfgbcfybb

    • +2
      не в той раскладке, простите.

      Хочу поделиться с хаброобществом своей статье о скорости селекторов и правильном их написании.

      mabp.kiev.ua/2009/02/07/speed-up-jquery-selectors/

      надеюсь будет полезно
      • 0
        Я капнул вам кармы, разместите просто запись у себя в блоге вида «Ссылка» на ваш материал.
        • 0
          пасибо, я сделал.
      • 0
        Кажется прилегла ваша статейка от хабраэффекта (
  • +6
    хочу уточнить насчет вот этого:
    $('#myImage').attr('src', 'image.jpg').load(function() {  
        alert('Картинка загружена');  
    });
    


    сработает ли alert() если картинка в кеше браузера и переключится моментально? не правильнее ли будет делать вот так:
    $('#myImage').load(function() {  
        alert('Картинка загружена');  
    }).attr('src', 'image.jpg');
    

    • +1
      Ваш код корректнее, однозначно.
    • 0
      Хм, похоже да, этот способ получше!
  • 0
    Отличная статья спасибо!
  • +1
    >>2. Используйте «шпаргалку» (cheat sheet)
    Мне очень сильно помогает шпаргалка сохраненная с visualjquery.com, может кому тоже поможет.
    • 0
      Вот тока её создатели что-то не хотят держать своё детище в актуальном состоянии.
  • +5
    По поводу анимации

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

    Для решения этой проблемы можно использовать одну недокументированную возможность функции animate

    //К, примеру, анимируем изменение height от 500 до 0
    $("#first_element").animate(
        {height:0},
        {
            duration: "fast",
            step: function(curr, _this) {
    			// функция вызывается каждый раз ДО изменения значения height у элемента
    			// curr будет содержать текущее значение от 500 до 0
    			
    			// изменим значение height, округлим значение (по-умолчанию height будет дробным)
    			// изменение curr не сохраняется, поэтому меняем _this.now
                _this.now = Math.floor(curr);
                
    			// теперь получим относительное изменение высоты
    			// т.е. X будет изменяться от 0 до 1
    			var x = (500 - curr) / 500;
    			
    			// будем менять значение высоты у любого элемента
    			// отдельный таймер не создается, поэтому все меняется при одном обновлении dom дерева
    			$("#second_element")
    				.css({height: 500 * x + "px", color: "rgb(" + (r + parseInt((0xFF - 0x00) * x)) + ", " + (g + parseInt((0xFF - 0x00) * x)) + ", " + (b + parseInt((0xFF - 0x00) * x)) + ")"});
    
            },
            complete: function()
            {
                // call oncomplete
            }
        }
    );
    


    Таким способом можно анимировать цвет, фон и т.д. без использования плагинов.
    • 0
      Штука интересная, интересно как бы получать и парсить rgb, а так же менять цвет из одного в другой таким вот методом.
  • +1
    Отличный материал, большое спасибо.
  • +1
    Спасибо, познавательно! =)
  • +1
    Спасибо, классная статейка. +1
  • 0
    все в одном месте, красиво и складно. да еще и с примерами. супер!
  • –2
    Ещё можно добавить к пункту "24. Возвращайте "false" для отмены поведения по-умолчанию":
    Можно вместо
    <a href="#" class="popup">Нажми меня, злодей!</a>
    писать
    <a href="javascript:void(0)" class="popup">Нажми меня, злодей!</a>
    Эффект будет тот же и при этом можно не писать return false; в конце функции.
  • 0
    Рекомендую изучить непосредственно сам javascript. Мне кажется вы сможете это сделать, но jquery застилает вам глаза.

    ЗЫ моя позиция: ничего не имею против использования фремвоков, но считаю что javascrit сам по себе дает куда большую свободу самовыражения.
    • 0
      Знаете как именно я в свое время понял JavaScript от и до? На примере изучения библиотечки Prototype, нашел внутри нее таааакой JavaScript, о каком не пишут ни в одном учебнике.
      • 0
        javascript.ru/ecmascript — а есть еще и такие учебники :)
        • 0
          Есть. Но все же, очень хорошо на живом примере все рассматривать. Вот у меня в свое время Прототайп и был таким примером.
  • 0
    Может я немного забыл селекторы в jquery.
    Но, думаю в пункте 24 вы пропустили точку (.)

    $('.popup').click(function(){
    // Код запуска popup'а
    });
    • 0
      Да, вы полностью правы, спасибо за поправку!
  • 0
    Спасибо, это самая лучшая статья по Jquery, которую я когда-либо видел!
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Большое Спасибо! Все советы очень полезные, подчеркнул для себя много нового!
  • 0
    Спасибо!
  • 0
    добавьте, пожалуйста, в раздел шпаргалок futurecolors.ru/jquery/
    Шпаргалка по актуальной версии
  • 0
    Хороший перевод, спасибо за статью.
  • 0
    Спасибо за статью! Понятно, доступно, для каждого! Есть, куда развиваться! :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.