Добрый день. Я сейчас прохожу курс повышения квалификации - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?
|
Практическое приложение
8.7.2. Кэш
Внутреннее кэширование
Кэш у jQuery крайне неразвит, если не сказать отсутствует, поэтому кэшируется только предыдущий элемент, выбранный в цепочке. Это можно наглядно рассмотреть на двух примерах.
Ситуация следующая: вы работаете со списком, у вас есть один из элементов li. Для того, чтобы получить все элементы, включая текущий, надо выбрать всех братьев (все, у кого родитель — это родитель текущего) этого элемента и добавить его самого:
$("#id").siblings().add("#id")
Так как он — прошлый элемент, с которым работали в цепочке вызовов, мы можем взять его из КЭШа:
$("#id").siblings().andSelf()
Конечно, в данном конкретном случаи быстрее было бы сделать
$("#id").parent().children()
Потому что siblings — это и есть выбор всех детей родителя. Но принцип использования этот пример иллюстрирует нормально.
Второй пример использования кэша — это простой возврат к предыдущей выборке, вместо того чтобы размазывать код на три строчки:
var elt = $("#id"); elt.children().css({/**/}) elt.click();
Можно после работы с детьми вернуться обратно к родителю и работать с ним дальше:
$("#id").children().css({/**/}).end().click()
Кэширование селекторов
Поскольку кэш так слабо развит, селекторы нужно кэшировать вручную. Давайте рассмотрим, например, вот такой код:
for(var i=0;i<1000;i $("ul").append=""("<li>"+i""/
Все работает и выглядит красиво, но и это можно оптимизировать. Если вынести выборку за пределы цикла, добавление новых элементов будет проходить быстрее:
var elts = $("ul"); for(var i=0;i<1000;i elts.append=""("<li>"+i+"</li>")
Буферизация
Но этот код можно заставить работать еще быстрее! Каждый раз, делая append, мы заставляем обновиться DOM-дерево и заставляем браузер перерисовать страницу. Этого можно избежать, придерживая вставку в DOM-дерево.
var str = ""; for(var i=0;i<1000;i str += ""<li>"+i+"</li>" $("ul").html(str);
Дело в том, что функции для работы с DOM-деревом у jQuery самые "тяжелые" (http://mabp.kiev.ua/2009/03/29/jquery-profiling/). Это объясняется просто. Все html-ноды, на которые повешены события через jQuery, имеют в себе атрибут с объектом jQuery. При удалении этих нод нужно следить, чтобы не было утечек памяти, и удалять эти атрибуты перед удалением ноды. В результате функции html и text вызывают функции полной очистки и только потом вставки нового содержимого:
jQuery(DOMElement).empty().append(text)
Функция empty выбирает все ноды и по очереди удаляет:
jQuery(DOMElement).children().remove()
А функция remove уже заботится, чтобы из элементов были удалены все дополнительные данные и события.
Джон Ресиг утверждал, что знает способ быстро удалить все это и что улучшит эти методы, но что-то воз и ныне там. Поэтому будем ждать улуч- шенных функций уже в jQuery 1.4.
Создание "на лету"
Прошлый пример, на самом деле, был нужен для того, чтобы подобраться поближе к интересному факту. Часто приходится создавать какие-то вспомогательные дивы, и, естественно, нас интересует самый эргономичный способ это сделать. Казалось бы, в чем проблема: кинул кусок html-кода, и jQuery сама все сделала. Возьмем самый простой и банальный пример: надо создать пустой див:
$("<div></div>")
или
$("<div/>")
Второй вариант в 5 раз быстрее первого. Но это, естественно, не все: если нам надо создать не пустой див, а содержащий текст, из прошлых заметок станет ясно, что функция text тяжелая, и выгоды от нее не будет, и стоит создавать див "как есть".
$("<div>text</div>")
И не создавать, а потом добавлять текст:
$("<div/>").text("text")
Но это не каcается создания атрибутов, для них используются намно- го более "легкие" функции attr/css/addClass (http://mabp.kiev.ua/2009/03/29/jquery-profiling/), вот тут-то и имеет смысл вместо
$("<div style='background:red;'/>")
писать
$("<div/>").css({background:'red'});
— это даст небольшой, но выигрыш.
8.7.3. События
Множественные события
$(window).bind("resize load",null,function(){ $("#id").css({width:document.clientWidth}) });
Только при этом не забываем, что поведение IE8 не соответствует стандартам, и при загрузке страницы сначала происходит событие resize, а только потом load.
То же самое корректно и в обратную сторону:
$(window).unbind("resize load");
Но это не работает в версии 1.2.6, точнее, работает только с именованными функциями, а с анонимными не годится, их надо удалять по одной.
Одно событие на много элементов
Если случается повесить события на длинный список:
var ul = $("<ul/>"); for(var i=0,j=1000;i<j;i++) $("<li>"+i+"</li>").click(function(e){ alert(this.innerHTML); }).appendTo(ul); ul.appendTo("body");
то в результате мы будем иметь 1000 одинаковых обработчиков событий. Вряд ли это добавит скорости нашей странице, поэтому можно воспользоваться маленькой хитростью и повесить всего один обработчик на родительский элемент:
var str = ""; for(var i=0,j=1000;i<j;i str += ""<li>"+i+"</li>"; $("<ul/>") .append(str) .click(function(e){ alert(e.target.innerHTML); }) .appendTo("body");