JQuery: по сравнению с живыми - PullRequest
2 голосов
/ 26 марта 2012

Мне любопытно, почему, когда я заменяю .live() на .on(), мои события не работают после вставки ответа AJAX с помощью метода html(). Предположим, у меня есть HTML структура:

<div class="a">
   <a href="" class="alert-link">alert</a>
   <a href="" class="ajax-update">update</a>
</div>

и код jquery что-то вроде:

$('.alert-link').on("click", function(){
 alert('abc');
 return false;
});

и ajax-update вызовет запрос, ответ которого будет

Оповещение обновление

и я вставлю его в parent(). Повторное нажатие alert-link приведет к перенаправлению на /, но если я изменю .on() на .live(), снова появится предупреждение. Что мне здесь не хватает? Я читал, что .on() является заменой .delegate() и .live().

Ответы [ 3 ]

7 голосов
/ 26 марта 2012

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

$('.alert-link').on("click", function(){

вам нужно использовать динамическую форму, подобную этой:

$(someStaticParentObject).on("click", '.alert-link', function(){

Это свяжет обработчик события с someStaticParentObject и затем использует делегированную обработку событиядля любых дочерних событий, которые происходят с элементом, который соответствует селектору '.alert-link'.Ваша версия немедленно связывалась с элементами '.alert-link', существовавшими на момент установки обработчика событий (статическая привязка), и не использовала делегированную обработку событий для обработки событий от объектов, которые еще не созданы.

См.эти предыдущие ответы дают хорошее объяснение .live() против .on() и почему .live() может привести к проблемам с производительностью в некоторых случаях:

Работает ли jQuery.on () для элементов, которыедобавлен после создания обработчика событий?

Как новый метод on () в jQuery сравнивается с методом live () в производительности?

В чем разница между jQuery.bind () и jQuery.on ()?

jQuery .live () и метод .on () для добавления события click после загрузки динамического html

Почему бы не довести делегирование событий Javascript до крайности?

В двух словах:

$(".item").live('click', fn);

функциональность эквивалентна:

$(document).on('click', '.item', fn);

Два основных недостатка .live():

  1. Он немедленно оценивает селектор ".item", который является просто потраченными впустую циклами, потому что результат не используется вообще.
  2. .live() жестко привязан к объекту документа.Он использует делегированную обработку событий, чтобы иметь возможность обрабатывать объекты, которые приходят и уходят, но все обработчики событий .live() назначены объекту документа.Если их много, это может стать большим узким местом в производительности, потому что каждое событие, которое всплывает в документе, должно оцениваться по отношению к селекторам всех .live() обработчиков событий..on(), с другой стороны, может быть привязан не только к объекту документа, но и к предку, который намного ближе к фактическому источнику событий, и когда есть много делегированных обработчиков событий, это может быть ОЧЕНЬ более эффективнымчтобы найти события ближе, так что только события, которые находятся близко к объекту, обрабатываются с помощью селекторов .on(), что повышает производительность.Например, описанные выше обработчики могут быть выполнены следующим образом:

    $("#container").on('click', '.item', fn);
    

, где #container является родителем динамических объектов .item.

4 голосов
/ 26 марта 2012

.on объединяет и заменяет .bind, .live и .delegate. Синтаксис $('selector').on('event', callback) является моральным эквивалентом bind, а не live.

Добавьте селектор фильтрации к вашему звонку на on:

$('container').on('click', 'child-filter', callback);

В этом случае

$('.a').on("click", ".alert-link", function(){
    alert('abc');
    return false;
});

Это было изменено, потому что более эффективно прикреплять обработчик делегата к более локализованному элементу контейнера, чем старый стиль .live присоединения обработчика к корню DOM.

Другими словами, даже если alert-link элементы будут появляться только внутри небольшого a div, с .live, jQuery прослушивает каждое отдельное событие клика на странице и сравнивает это делегированному селектору. Будучи более целенаправленным, jQuery должен обрабатывать только клики по элементам в пределах a.

2 голосов
/ 26 марта 2012

Это действительно замена для .delegate и .live, но вы должны передать некоторые дополнительные параметры:

var container = $('.a').on('click', '.alert-link', function() {
    alert('abc');
    return false;
}).on('click', '.ajax-update', function() {
    // something that uses AJAX to update .a, like:
    container.load('some-url');
    return false;
});

Для получения дополнительной информации см. Документацию .

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