Передовые методы привязки jQuery

В последнее время при связывании событий click в jQuery я спрашиваю, следует ли использовать ярлык jQuery click() или если я должен сам указать .on('click', ...).

Функция . click(). в jQuery - это просто ярлык. Для меня имеет смысл использовать, потому что jQuery обрабатывает все за кулисами, учитывая предпочтительный метод для используемой версии jQuery. Когда я обновил свои сценарии из jQuery 1.6 → 1.7, я знаю, что все мои click() перешли от ярлыка к bind() к предпочтительному методу on(). Это одно, по-видимому, достаточно разумно использовать ярлыки.

... однако....

Тревор Бернем, которого я очень уважаю, говорит в своей электронной книге Async Javascript, что он

... предпочитают последовательно использовать более мощные bind/on) (над кликом)

Это меня смущает, и мне было интересно, почему использование bind/on является "более мощным".

Что вы нашли, чтобы быть лучшими практиками при связывании событий с ярлыками в jQuery? Использовать ярлык или сделать это самостоятельно?

Ответы

Ответ 1

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

Чем мощнее идет .on, вы можете делегировать события, когда ярлыки всегда работают с элементом напрямую. Например, $('body').on('click', '.button', function(){}); будет работать для каждого элемента .button даже тех, которые добавлены после факта с помощью ajax или иным образом. Хотя ярлык не может сделать это, $('.button').click(function(){}); - единственный способ добавить слушателя к .button и не имеет делегирования, поэтому элементы .button, добавленные позже, не будут иметь этого связывания.

Прямые не делегированные события (например, ярлыки) для нескольких элементов также немного менее эффективны, чем делегированные события на родительском объекте. Например: допустим, что на странице есть 15 .button элементов, $('.button').click(... будет циклически перебирать все 15 элементов и добавлять к ним прослушиватель событий; однако $('#parentElem').on('click', '.button', ... просто присоединяет один прослушиватель событий к #parentElem, который проверяет цель, поэтому один подключаемый и один прослушиватель, а также цикл и 15 слушателей.

И, наконец, .on имеет то преимущество, что вы можете присоединить функцию к элементу из нескольких событий, что невозможно с помощью ярлыков, например: $('.button').on('click mouseover keyup', ... функция будет запускаться с помощью щелчка, мыши или клавиатуры!


Давайте еще раз скажем, что в div называется 15 .button элементов, называемых #parent

Ярлык:

 $('.button').click(turnRed);
 $('.button').mouseover(turnRed);
 $('.button').keyup(turnRed);

 function turnRed(){
      $(this).css('color','red');
 }
  • Создано 4 объекта jQuery (да, я знаю, вы можете кэшировать его на 2 объекта, но это пример)
  • 3 элемента цикла по 15 каждый, поэтому jQuery хитов здесь 45 раз и прикрепляет слушателей.
  • 45 слушателей всех событий
  • Будущие элементы .button, добавленные в сцену, не turnRed

.on обработчик:

 $('#parent').on('click mouseover keyup', '.button', turnRed);

 function turnRed(){
      $(this).css('color','red');
 }
  • Созданы 2 созданных объекта jQuery.
  • Нет цикла элементов, поэтому jQuery удаляет элементы один раз
  • 3 слушателя всех событий
  • Будущие элементы .button, добавленные в сцену, фактически будут turnRed

Здесь .on явно имеет преимущество


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

$('#button').click(... почти идентичен $('#button').on('click', ... (см. ответ @Fabrício Matté), и если мы просто хотим добавить один прослушиватель к одному событию, то сила .on - спорная точка.

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

Ответ 2

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

Внутри объектов jQuery 'extend (строка 3754) jQuery выполняет итерацию по всем этим именам методов по строке 3909:

размытие фокус фокус фокус нагрузка изменение размера прокрутка разгрузка клик dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keyup ошибка контекстного меню

Создание сокращенных методов, которые вызывают метод .on для данного метода без передачи атрибута selector при вызове этих методов (строка 3921):

this.on( name, null, data, fn )

Это означает, что у него будет отсутствие события делегирования.


Что вы нашли, чтобы быть лучшими практиками при связывании событий с ярлыками в jQuery? Использовать ярлык или сделать это самостоятельно?

Единственное различие между вызовом

$(selector).eventname(function(){...})

и

$(selector).on('eventname', function(){...})

Это то, что сокращенный метод имеет накладные расходы другого вызова функции (который ничтожно минимален).

Обновление: При создании пользовательской сборки jQuery с Grunt методы сокращения могут быть исключены с параметром custom:-event-alias для еще более мелкой сборки (Документы здесь). Хотя, я лично склонен придерживаться CDN-сборок.


Что касается того, как работает делегирование событий и когда это предпочтительнее, проверьте docs и @Ответ Fresheyeball.