Чим відрізняється `on` та` live` або `bind`?


172

У jQuery v1.7on був доданий новий метод . З документації:

'Метод .on () приєднує обробники подій до поточно вибраного набору елементів об'єкта jQuery. Станом на jQuery 1.7, метод .on () забезпечує всю функціональність, необхідну для приєднання обробників подій. '

Яка різниця з liveі bind?



До того, як запитати, не вдалося шукати щось подібне. Дякую!
Дієго

Відповіді:


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 сказав найбільш зрозумілу відповідь. Будь ласка, додайте порівняння між ввімкненим і делегованим для завершення відповіді? Дякую!
Дієго

lols, ви додали джерело jquery за 4 секунди до мене: D btw live еквівалентний контекст - це документ, а не 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 служить загальною заміною для відв'язування, неживого та відмежування.
Енді Е

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 стовпців, і кожна з 100000 комірок містить прапорець, натисканням якого ви хочете обробити. Додавання 100000 обробників подій потребує багато часу при завантаженні сторінки. Створення однієї події на рівні таблиці та використання делегування подій на кілька порядків ефективніше. Ціль події буде отримано під час виконання події. " this" буде таблицею, але " event.target" буде вашим звичним " this" у clickфункції. Тепер приємним onє те, що " this" завжди буде ціллю події, а не контейнером, до якого вона приєднана.


Чи не делегат приходить з неповнолітнім?
DaveWalley

1
Так. хороші кров’янисті виділення. Ви
навчаєтесь

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у більшості випадків


3

(Моє вступне речення мало більше сенсу, перш ніж ви змінили питання. Спочатку ви сказали "У чому різниця live?")

onце більше, delegateніж це, як live, в основному, це уніфікована форма bindі delegate(насправді команда сказала, що її мета - "... уніфікувати всі способи приєднання подій до документа ..." ).

liveв основному on(або delegate) додається до документа в цілому. Це застаріло з версії 1.7 на користь використання onабо delegate. Йдучи вперед, я підозрюю, що ми побачимо код, використовуючи onвиключно, а не використовуючи bindабо delegate(або live) ...

Тож на практиці ви можете:

  1. Використовуйте onяк bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Використовуйте на onкшталт 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);

1
На сторінці, яку я пов’язував, написано: "Якщо в сторінку вводиться новий HTML, виберіть елементи та приєднайте обробники подій після того, як новий HTML буде розміщений на сторінці. Або використовуйте делеговані події, щоб долучити обробник подій, як описано далі". . Так що, швидше за все, зв'язувати, а не жити. Маю рацію?
Дієго

@Diego: onце поєднання bindі delegate, як я вже говорив, що не дуже схоже live. Ви можете використовувати на onзразок bind(прикріпити обробник безпосередньо до елемента), або ви можете використовувати onяк delegate(прикріпити обробник до елемента, але запустити подію лише у тому випадку, якщо фактичний натиснутий елемент відповідає селектору, і як би цей елемент був одним подія сталася на - наприклад, делегування події), або ви можете використовувати її як live( delegateвикористовуючи документ як корінь). Саме делегація подій робить корисною, якщо ви додаєте елементи динамічно.
TJ Crowder

1
старе живе також можна використовувати як делегат: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );Насправді в старому джерелі jQuery вони використовувались як загальний випадок, а делегат - як окремий випадок, що зробило це ще більш заплутаним, коли ви думаєте про це.
Esailija

@Esailija: Досить справедливо. Я не думаю, що це використання, про яке стало відомо, тому що вони додали delegateправильно, але все-таки. :-)
TJ Crowder


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/…
Олександр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.