В чем разница между `on` и` live` или `bind`?

172

В jQuery v1.7 новый метод,on был добавлен . Из документации:

«Метод .on () присоединяет обработчики событий к текущему выбранному набору элементов в объекте jQuery. Начиная с jQuery 1.7, метод .on () предоставляет все функции, необходимые для подключения обработчиков событий. '

Какая разница с liveи bind?

Диего
источник
5
связанные : В чем разница между jQuery .live () и .on ()
Феликс Клинг
Пришлось искать что-то подобное, прежде чем спрашивать и не удалось. Спасибо!
Диего

Ответы:

329

on()это попытка объединить большинство функций привязки событий jQuery в одну. Это дополнительный бонус прибирать неэффективность с liveпротив delegate. В будущих версиях jQuery эти методы будут удалены и только onи oneостанутся.

Примеры:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

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

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

См. Https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 .

Энди Э
источник
Как сказал @JamWaffles самый понятный ответ. Не могли бы вы добавить сравнение между on и делегатом, чтобы завершить ответ? Спасибо!
Диего
lols, вы добавили источник jquery за 4 секунды до меня: D Кстати, живой эквивалентный контекст - это документ, а не document.body
Esailija
1
Вместо этого вы можете ссылаться на тег 1.7, иначе будущие изменения могут сделать вашу ссылку недействительной (не указывать на правильное местоположение): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Феликс Клинг
3
$(document.body).delegate("click", ".mySelector", fn);должно быть$(document.body).delegate(".mySelector", "click", fn);
Сонни
2
@dsdsdsdsd, off служит универсальной заменой unbind, unlive и undelegate.
Энди Э
12

onв природе очень близко к delegate. Так почему бы не использовать делегат? Это потому, onчто не приходит один. есть off, чтобы отменить привязку события и oneсоздать событие, которое будет выполнено только один раз. Это «пакет» нового события.

Основная проблема liveзаключается в том, что он прикрепляется к «окну», заставляя событие щелчка (или другое событие) на элементе глубоко внутри структуры страницы (dom) «всплывать» вверх страницы, чтобы найти событие Хендлер готов разобраться с этим. На каждом уровне должны быть проверены все обработчики событий, это может сложиться быстро, если вы делаете глубокую имбрикацию ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Так что, bindкак clickи другие ярлыки событий ярлыка, прикрепляются непосредственно к цели события. Если у вас есть таблица, скажем, 1000 строк и 100 столбцов, и каждая из 100 000 ячеек содержит флажок, щелчок которого вы хотите обработать. Присоединение 100'000 обработчиков событий займет много времени при загрузке страницы. Создание одного события на уровне таблицы и использование делегирования событий на несколько порядков эффективнее. Цель события будет получена во время выполнения события. " this" будет столом, но " event.target" будет вашим обычным делом "this " в clickфункции. Теперь хорошо то, onчто " this" всегда будет целью события, а не контейнером, к которому она прикреплена.

roselan
источник
Не делегат приходит с undelegate?
Дейв Уолли
1
Ага. хорошее определение. Ты учишься каждый день;) (Документ сильно улучшился с 2011 года)
roselan
5

с помощью .onметода это можно сделать .live, .delegateи .bindс той же функцией, но можно .live()только с помощью .live()(делегирование событий в документ).

jQuery("#example").bind( "click", fn ) знак равно jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) знак равно jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) знак равно jQuery( document ).on( "click", "#example", fn )

Я могу подтвердить это непосредственно из источника jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery (this.context)? this.context=== documentв большинстве случаев

Esailija
источник
3

(Мое вступительное предложение имело больше смысла, прежде чем вы изменили вопрос. Первоначально вы сказали: «В чем разница live?»)

onэто больше похоже на то, на delegateчто это похоже live, это в основном унифицированная форма bindи delegate(на самом деле команда заявила, что ее целью является "... объединить все способы прикрепления событий к документу ..." ).

liveв основном on(или delegate) прикреплен к документу в целом. Начиная с версии v1.7 , он устарел в пользу использования onили delegate. В дальнейшем я подозреваю, что мы увидим код, использующий onисключительно, а не используя bindили delegate(илиlive ) ...

Итак, на практике вы можете:

  1. Используйте onкак bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Используйте onlike delegate(делегирование события коренится в данном элементе):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. Используйте onлайк live(делегирование событий, основанное на документе):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
TJ Crowder
источник
1
На странице, на которую я ссылаюсь, написано: «Если на страницу внедряется новый HTML, выберите элементы и прикрепите обработчики событий после того, как новый HTML добавлен на страницу. Или используйте делегированные события, чтобы присоединить обработчик событий, как описано далее». , Так что скорее связывай, а не живи. Я прав?
Диего
@Diego: onэто сочетание bindи delegate, и, как я уже сказал, не очень похоже live. Вы можете использовать onlike bind(прикрепить обработчик непосредственно к элементу), или вы можете использовать onlike delegate(прикрепить обработчик к элементу, но вызвать событие, только если выбранный элемент соответствует селектору, и как будто этот элемент был событие произошло (например, делегирование события), или вы можете использовать его как live( delegateиспользуя документ в качестве корня). Именно делегирование событий делает его полезным, если вы добавляете элементы динамически.
TJ Crowder
1
Старый лайв также можно использовать как делегат: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );На самом деле в старом исходном коде jQuery они использовали лайв в качестве общего случая и делегат в качестве особого случая, что еще больше запутало ситуацию, когда вы об этом думаете.
Esailija
@Esailija: Достаточно справедливо. Я не думаю, что это использование, которое стало известным, потому что они добавили delegateпрямо быстро, но все же. :-)
TJ Crowder
2

live это ярлык для .on () сейчас

//from source http://code.jquery.com/jquery-1.7.js
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

также этот пост может быть полезен для вас http://blog.jquery.com/2011/11/03/jquery-1-7-released/

doochik
источник
2

Там нет одного для основного варианта использования. Эти две линии функционально одинаковы

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () также может выполнять делегирование событий и является предпочтительным.

.bind () на самом деле просто псевдоним для .on () сейчас. Вот определение функции связывания в 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

Идея добавления .on () заключалась в том, чтобы создать единый API событий, а не иметь несколько функций для привязки событий; .on () заменяет .bind (), .live () и .delegate ().

Дэн
источник
0

Что-то, о чем вы должны знать, если хотите связать обработчики событий с элементом - обратите внимание, к какому элементу был прикреплен обработчик!

Например, если вы используете:

$('.mySelector').bind('click', fn);

вы получите обработчики событий, использующие:

$('.mySelector').data('events');

Но если вы используете:

$('body').on('click', '.mySelector', fn);

вы получите обработчики событий, использующие:

$('body').data('events');

(в последнем случае соответствующий объект события будет иметь selector = ". mySelector")

Александр
источник
eventsв любом случае недокументировано, и я думаю, что это больше не работает в 1.9
Джон Дворжак
Правильно. Можно использовать _data вместо данных в более новых версиях. Ответ был о разнице в «владельце события», а не о точном синтаксисе для старых или новых версий. Есть другие посты о точном синтаксисе для разных версий JQuery. Например stackoverflow.com/questions/2518421/…
Александр,