Связывание событий в jQuery очень дорого или очень недорого? - PullRequest
32 голосов
/ 25 мая 2009

Я просто написал функцию $ (). Bind ('event'), а затем подумал, что этот вид вызова может быть очень дорогим, если jQuery должен пройти через каждый элемент в DOM, чтобы связать это событие.

Или, может быть, это так же эффективно, как и событие. Документы jQuery, которые я прочитал, не проясняют это. Есть мнения?

Ответы [ 2 ]

71 голосов
/ 25 мая 2009

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

Что касается селекторов, просто убедитесь, что вы не используете чистые селекторы имен классов, такие как .myclass. Если вы знаете, что класс myclass всегда будет в элементе <div>, сделайте ваш селектор div.myclass, так как это поможет jQuery быстрее находить подходящие элементы. Кроме того, не пользуйтесь jQuery, предоставляя ему огромные строки селектора. Все, что он может делать со строковыми селекторами, он также может делать с помощью функций, и это сделано преднамеренно, поскольку это (незначительно, по общему признанию) быстрее сделать это таким образом, поскольку jQuery не нужно сидеть сложа руки, чтобы разобрать вашу строку, чтобы выяснить, что ты хочешь. Так что вместо $('#myform input:eq(2)'); вы можете сделать $('input','#myform').eq(2);. Определяя контекст, мы также не заставляем jQuery смотреть куда угодно, что намного быстрее. Подробнее об этом здесь .

Что касается количества связываний: если у вас относительно небольшое количество элементов, то у вас все должно быть в порядке - все, что угодно, до 200, 300 потенциальных совпадений элементов будет хорошо работать в современных браузерах. Если у вас есть больше, чем это, вы можете вместо этого заглянуть в делегирование событий.

Что такое делегирование событий? По сути, когда вы запускаете такой код:

$('div.test').click(function() {
    doSomething($(this));
});

jQuery делает что-то подобное за кулисами (связывая событие для каждого соответствующего элемента):

$('div.test').each(function() {
    this.addEventListener('click', function() {
        doSomething(this);
    }, false);
});

Это может стать неэффективным, если у вас большое количество элементов. С делегированием событий вы можете сократить количество привязок до одного. Но как? У объекта события есть свойство target, которое позволяет узнать, на каком элементе произошло событие. Таким образом, вы можете сделать что-то вроде этого:

$(document).click(function(e) {
    var $target = $(e.target);
    if($target.is('div.test')) { // the element clicked on is a DIV
                                 // with a class of test
       doSomething($target);
    }
});

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

Мораль этой истории? Если вас беспокоит количество привязок, ваш скрипт просто заменит .bind на .live и убедитесь, что у вас есть умные селекторы.

Обратите внимание, что не все события поддерживаются .live. Если вам нужно что-то, что не поддерживается этим, вы можете проверить плагин livequery , который работает на стероидах.

0 голосов
/ 25 мая 2009

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

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

Как правило, я считаю, что это очень недорогая операция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...