Об изменениях в jQuery 1.4 по сравнению с предыдущей версией

Версия для печатиВерсия для печати

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

Значительное увеличение скорости исполнения популярных методов

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

Количество вызовов популярных методов jQuery

В jQuery 1.4 мы значительно снизили сложность наиболее популярных методов. Полная информация об их производительности находится ниже по тексту.

Простые функции установки значений (setter)

Теперь вы можете передать функцию в качестве аргумента в метод .attr(), и возвращаемое этой функцией значение будет установлено в качестве соответствующего атрибута. Возможность установки значений с помощью функций реализована во следующих методах: .css(), .attr(), .val(), .html(), .text(), .append(), .prepend(), .before(), .after(), .replaceWith(), .wrap(), .wrapInner(), .offset(), .addClass(), .removeClass() и .toggleClass().

Кроме того, для следующих функций, в качестве второго параметра функции передается текущее значение: .css(), .attr(), .val(), .html(), .text(), .append(), .prepend(), .offset(), .addClass(), .removeClass() и .toggleClass().

Например, можно написать так:

// найти все амперсанды в тегах A и обернуть тегом span
$('a').html(function(i,html){
  return html.replace(/&amp;/gi,'<span class="amp">&amp;</span>');
});
 
// Добавить какую-либо информацию к тегам A
$('a[target]').attr("title", function(i,title){
  return title + " (Opens in External Window)";
});

Атрибуты (Attributes)

Улучшена производительность функций .css() и .attr().

Производительность .css() и .attr()

Возможность установки значений в методе .attr() с помощью функций

Кроме использования функций для установки значений в методе .attr(), вы также можете использовать текущее значение атрибута в этой функции.

jQuery('<img src="enter.png" alt="введите Ваше имя" />')
.attr("alt", function(index, value) {
    return "Пожалуйста, " + value;
});

.val( Function )

<input class="food" type='text' data-index="0" />
<input class="food" type='text' data-index="1" />
jQuery("input:text.food").hide();

jQuery("<ul class='sortable'><li>Peanut Butter</li><li>Jelly</li></ul>")
  .sortable()
  .bind("endsort", function() {
    $(":text.food").val(function() {
      return $("ul.sortable li:eq(" + $(this).attr("data-index")  + ")").text();
    });
  });

Теперь метод .text() работает с текстом и узлами CDATA

Ядро (Core)

Быстрое создание элементов

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

jQuery("<div/>", {
    id: "foo",
    css: {
        height: "50px",
        width: "50px",
        color: "blue",
        backgroundColor: "#ccc"
    },
    click: function() {
       $(this).css("backgroundColor", "red");
    }
}).appendTo("body");

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

.eq(-N), .get(-N)

Теперь вы можете передать отрицательные значения в методы .get() и .eq(). Например, вы можете выбрать второй с конца блок div или получить доступ к элементу DOM следующим образом:

$("div").eq(-2);
$("div").get(-2);

Новые функции .first() и .last()

Для удобства предусмотрены простые функции .first() и .last(), аналогичные .eq(0) и .eq(-1) соответственно.

Новый метод .toArray()

.get() возвращает массив из набора jQuery. Для большей ясности в jQuery 1.4 вы можете использовать метод .toArray() для достижения того же эффекта. Однако, в отличие от .get() метод .toArray() не имеет.

jQuery() возвращает пустой набор

В jQuery 1.3 метод jQuery() возвращал набор jQuery, содержащий только элемент document. В jQuery 1.4 он возвращает пустой набор jQuery. Это может быть полезно для создания пустого набора и динамического добавления в него элементов. Примечание: Метод jQuery().ready() также работает в версии 1.4, но он устарел. Пожалуйста, используйте jQuery(document).ready() или jQuery(function(){}).

jQuery(“TAG”)

Увеличена скорость обращения к элементам при передаче единственного тега.

jQuery(“<div>”), jQuery(“<div/>”) и jQuery(“<div></div>”)

При вызове всех трёх функций для создания элементов используется функция document.createElement, что привело к увеличению производительности метода jQuery("<div></div>"). Обратите внимание, что если вы указываете атрибуты в передаваемых элементах, то используется метод innerHTML.

CSS

Производительность метода .css() увеличена в 2 раза.

Производительность .css()Производительность методов .addClass(), .removeClass() и .hasClass() увеличена в 3 раза.

Производительность .addClass(), .removeClass(), hasClass

.toggleClass() может переключать несколько классов одновременно

Теперь вы можете вызвать метод .toggleClass() с несколькими именами классов, и все они будут переключаться.

$("div").toggleClass("current active");

Данные (Data)

.data() возвращает объект, а .data(Object) устанавливает объект

Иногда нужно работать с данными, прикрепленными к элементу в виде объекта. Часто необходимо скопировать все данные из одного элемента в другой. В jQuery 1.4 метод .data() без параметров возвращает весь объект целиком, а .data(Object) устанавливает объект. Имейте в виду, что объект включает события, прикрепленные к элементу, так что будьте осторожны при его использовании.

Кеш данных больше не создается, если он не нужен

jQuery uses a unique expando on DOM elements that is used to get the .data() for a particular element. jQuery now avoids creating that expando when data is looked up but no data has been added. This potentially increases performance and avoids polluting the DOM in these cases.

Эффекты (Effects)

Per-property Easing

Теперь вы можете указать функции управления анимацией (easing) для отдельных свойств элементов.

$("#clickme").click(function() {
  $("div").animate({
    width: ["+=200px", "swing"],
    height: ["+=50px", "linear"],
  }, 2000, function() {
      $(this).after("<div>Анимация завершена.</div>");
  });
});

События

Новый метод: jQuery.proxy()

Если вы хотите достичь того, чтобы “this” внутри функции был прочно связан с определённым значением, вы можете использовать jQuery.proxy, чтобы возвратить новую функцию с нужной областью видимости.

var obj = {
  name: "John",
  test: function() {
    alert( this.name );
    $("#test").unbind("click", obj.test);
  }
};
$("#test").click( jQuery.proxy( obj, "test" ) );

Множественная привязка событий

Теперь вы можете передать методу .bind() объект, содержащий несколько событий.

$("div.test").bind({
  click: function(){
    $(this).addClass("active");
  },
  mouseenter: function(){
    $(this).addClass("inside");
  },
  mouseleave: function(){
    $(this).removeClass("inside");
  }
});

События `change` и `submit` унифицированы

События change и submit надежно работают во всех браузерах для нормальных событий и событий реального времени. Мы перекрываем нормальные события change и submit в Internet Explorer и заменяем их событиями, которые работают так же, как и во всех остальных браузерах.

Новые события: `focusin` и `focusout`

Вообще события focusin и focusout являются эквивалентами focus и blur, but bubble, which helps tremendously if you are writing your own event delegation behavior. Пожалуйста, заметьте, что функции `focus` и `blur` не работают с методом live(); this was a design decision due to the DOM Events spec defining focus/blur do not bubble.

$("form").focusout(function(event) {
    var tgt = event.target;
    if (tgt.nodeName == "INPUT" && !tgt.value) {
        $(tgt).after("<span>nothing here</span>");
    }
});

Манипуляция

Производительность увеличена

Несколько методов манипуляции с DOM стали значительно быстрее в jQuery 1.4. Увеличена производительность методов .append(), .prepend(), .before() и .after().

Производительность операций вставки в DOMПроизводительность .html() улучшена приблизительно в 3 раза.

Производительность .html()Скорость выполнения .remove() и .empty() увеличена в 4 раза.

Производительность .remove() и .empty()

Новый метод .detach()

Метод detach() удаляет элемент из DOM, но не удаляет связанные обработчики событий. Этот метод подходит для временного удаления элемента с последующим его восстановлением.

var foo = $("#foo").click(function() {
    // do something
});
foo.detach();
// foo retains event handlers
foo.appendTo("body");

Новый метод unwrap()

Метод unwrap() удаляет переданный ему элемент, оставляя его потомков без изменений. Подобно этому:

<body>
    <div>
        <p>annie</p> <p>davey</p> <p>stevie</p>
    </div>
</body>
$('div').unwrap();
<body>
   <p>annie</p> <p>davey</p> <p>stevie</p>
</body>

Кеширование в domManip

jQuery кэширует узлы, созданные с использованием таких методов, как jQuery("<div>") и .after("<div>"). Благодаря этому увеличивается производительность на страницах, на которых выполняются DOM-манипуляции со строками, использующих эти методы.

before, after, replaceWith с несвязанными узлами

Теперь вы можете применять before, after и replaceWith к узлам, которые не прикреплены к DOM. Это позволит вам делать более сложные манипуляции  перед вставкой законченной структуры в дерево DOM.

jQuery("<div/>").before("<p>Привет</p>").appendTo("body")

.clone(true) также клонирует и данные

В jQuery 1.3 метод .clone(true)не клонировал данные. В jQuery 1.4 он выполняет клонирование данных, что означает и возможность клонирования событий. Он использует ту же семантику, что и jQuery.extend, так что простые объекты и массивы будут клонироваться, а пользовательские объекты нет.

Смещение (Offset)

.offset( coords | Function )

Теперь можно установить смешение элемента, причем метод offset(), как и другие функции установки, может принимать функцию в качестве аргумента.

Организация очередей (Queueing)

Чтобы улучшить работу с очередями, мы полностью пересмотрели их организацию, отличную от стандатной fx.

Новый метод .delay()

Метод .delay() приводит к задержке всех дальнейших элементов в очереди на определённое количество миллисекунд. По умолчанию используется очередь эффектов fx. Вы можете указать альтернативную (другую) очередь в качестве второго аргумента функции delay.

$("div").fadeIn().delay(4000).fadeOut();

Queue next()

В jQuery 1.4 the function that’s called is passed in another function, as the first argument, that when called automatically dequeues the next item and keeps the queue moving.

jQuery("div").queue("ajax", function(next) {
  var self = this;
  jQuery.getJSON("/update", function(json) {
    $(self).html(json.text);
    next();
  };
}).queue("ajax", function() {
  $(this).fadeIn();
});

.clearQueue()

Теперь очередь можно очищать. Метод .clearQueue() удаляет все невыполненные функции из очереди, но не останавливает функции, выполняемые в данный момент. Использование .clearQueue() без параметров приведет к очистке fx очереди.

Селекторы (Selectors)

"#id p" стал быстрее. Любая строка селекторов, которая начинается с идентификатора работает более оптимизированно. Селекторы, начинающиеся с ID, всегда будут быстрее.

Обход (Traversing)

.index(), .index(String)

Метод .index() был переписан и стал более удобным.

Теперь вы можете получить индекс элемента по отношению к элементам того же уровня:

// получить индекс первого <li class="current"> по отношению к его "братьям":
$("li.current").index()

Вы можете получить индекс элемента по отношению к текущей коллекции jQuery, передав в качестве аргумента селектор или элемент DOM:

// получить индекс <h3 id="more-info"> по отношению ко всем элементам <h3>:
$("#more-info").index("h3")

Новый метод .has()

Этот метод аналогичен фильтру :has(). Он принимает набор jQuery и возвращает те элементы из этого набора, которые содержат указанный в параметре селектор.

Новые методы .nextUntil(), .prevUntil(), .parentsUntil()

Новые методы типа "until" похожи на .nextAll(), .prevAll(), .parents(), но в качестве аргумента принимают селектор, по достижении которого обход останавливается.

.add(String, Element)

Теперь метод .add() может использовать контекст. Эта функция особенно полезна, если вы хотите добавить дополнительные элементы (например, возвращенные ajax-запросом) и затем манипулировать ими вместе с остальными элементами.

.closest(filter, DOMElement)

Метод closest теперь может принимать в качестве второго аргумента контекст в виде DOMElement. Как правило, при использовании контекста метод closest() работает быстрее.

Утилиты (Utilities)

jQuery.isEmptyObject()

Эта функция возвращает true, если объект не содержит ни одного свойства. Теперь достаточно передать объект в jQuery.isEmptyObject(), и jQuery выполнит итерации по переданному объекту без каких-либо других проверок.

jQuery.isPlainObject()

jQuery.isPlainObject() возвратит true, если объект является литералом, и false, если объект другого типа.

jQuery.contains()

jQuery.contains() возвратит true, если оба аргумента узлы DOM и второй аргумент находится внутри первого.

jQuery.noop

jQuery.noop — пустая функция, которая может быть использована, если вам просто требуется функция для каких-либо целей.

jQuery.unique()

В jQuery 1.4 метод jQuery.unique(), используемый разработчиками внутри библиотеки для создания набора jQuery, удаляет дубликаты из набора и возвращает остальные элементы в том же порядке, что они были и на входе.

Прочее

jQuery.browser теперь может определять тип движка браузера

Например, вы можете проверить, является ли Webkit движком браузера с помощью функции jQuery.browser.webkit.

Улучшенная поддержка апплетов

jQuery больше не пытается присоединить события или данные к Java-апплетам (которые генерируют исключения).

Теперь для сжатия исходного кода библиотеки используется Closure Compiler вместо YUI Min

Внутренняя реорганизация кода

Одним из главных изменений в новой версии было создание более четкой и понятной кодовой базы.

Вот некоторые из изменений:

  • Старый файл ‘core.js’ был разделен на ‘attribute.js’, ‘css.js’, ‘data.js’, ‘manipulation.js’, ‘traversing.js’ и ‘queue.js’.
  • Событие ready было перемещено в core.js (так как это базовая часть jQuery).
  • Большая часть кода соответствует новым рекомендациям по оформлению кода jQuery.
  • Логика для работы с CSS и атрибутами была разделена и стала менее запутанной.

Тестирование

В jQuery 1.4 мы исправили 207 багов (по сравнению с 97 багами в релизе версии 1.3).

Кроме того мы увеличили количество тестов с 1504 в jQuery 1.3.2 до 3060 в jQuery 1.4.

Набор тестов jQuery был на 100% пройден всеми популярными браузерами (Safari 3.2, Safari 4, Firefox 2, Firefox 3, Firefox 3.5, IE 6, IE 7, IE 8, Opera 10.10 и Chrome).

Тест нашего журнала

Тест был проведен на компьютере с характеристиками: Intel Pentium IV 3ГГц, 2ГБ RAM, ОС Windows XP Professional SP 2.

 Функция  jQuery 1.3.2  jQuery 1.4

Opera 10.10

class
addClass 125 15
addClassMulti 266 47
hasClass 609 63
removeClass 266 141
removeClassMulti 187 156
attr
css 188 125
cssMulti 593 485
attr 187 110
attrMulti 328 250
dom
appendLI 31 47
appendLIs 188 125
appendTR 31 31
appendTRs 78 32
appendToA 437 344
replaceContents 172 94
createElement 15 31
empty
empty 921 250
remove 4516 375
Итог 9138 2721

Mozilla Firefox 3.5.7

class
addClass 226 54
addClassMulti 364 42
hasClass 519 77
removeClass 349 100
removeClassMulti 280 103
attr
css 332 151
cssMulti 971 542
attr 241 175
attrMulti 436 265
dom
appendLI 157 100
appendLIs 367 267
appendTR 168 38
appendTRs 234 71
appendToA 743 539
replaceContents 539 185
createElement 40 34
empty
empty 1509 328
remove 7447 672
Итог 14922 3743

Internet Explorer 8

class
addClass 343 157
addClassMulti 563 188
hasClass 1375 313
removeClass 609 281
removeClassMulti 485 297
attr
css 359 250
cssMulti 1109 812
attr 625 390
attrMulti 1516 1094
dom
appendLI 187 140
appendLIs 282 188
appendTR 141 63
appendTRs 172 93
appendToA 1625 1329
replaceContents 672 203
createElement 47 31
empty
empty 3047 781
remove 13781 3562
Итог 26938 10172

Google Chrome 3

class
addClass 86 14
addClassMulti 178 26
hasClass 268 24
removeClass 152 65
removeClassMulti 97 43
attr
css 170 86
cssMulti 669 403
attr 120 88
attrMulti 328 173
dom
appendLI 48 36
appendLIs 81 75
appendTR 45 25
appendTRs 61 33
appendToA 262 256
replaceContents 200 87
createElement 12 12
empty
empty 646 207
remove 2583 344
Итог 6006 1997

Apple Safari 4

class
addClass 69 28
addClassMulti 94 33
hasClass 293 49
removeClass 111 56
removeClassMulti 86 52
attr
css 176 99
cssMulti 565 361
attr 125 86
attrMulti 231 154
dom
appendLI 39 35
appendLIs 61 64
appendTR 27 32
appendTRs 39 34
appendToA 242 257
replaceContents 153 82
createElement 10 9
empty
empty 640 239
remove 2811 356
Итог 5772 2026

Таким образом по производительности лидирует Chrome 3, незначительно опережая Safari 4. Браузеры Opera и Firefox догоняют их с отставанием в скорости на 136% и 187% соответственно. Как и можно было ожидать в конце плетётся IE8, показав 5-кратное отставание в производительности от лидеров. Причем сей убогий браузер в ходе тестирования на двух последних тестах несколько раз зависал.

Статья основана на публикации "jQuery 1.4 Released".

 

Ваша оценка: Нет Средняя: 9.6 (8 голосов)