jQuery .live () и метод .on () для добавления события щелчка после загрузки динамического HTML - PullRequest
203 голосов
/ 06 января 2012

Я использую jQuery v.1.7.1, где метод .live () явно устарел.

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

$('#parent').load("http://..."); 

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

$('#parent').click(function() ...); 

или

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

Как правильно выполнить эту функцию?Кажется, он работает только с .live (), но я не должен использовать этот метод.Обратите внимание, что #child является динамически загружаемым элементом.

Спасибо.

Ответы [ 7 ]

586 голосов
/ 06 января 2012

Если вы хотите, чтобы обработчик кликов работал для элемента, который загружается динамически, тогда вы устанавливаете обработчик событий на родительский объект (который не загружается динамически) и назначаете ему селектор, который соответствует вашему динамическому объекту, например так:

$('#parent').on("click", "#child", function() {});

Обработчик события будет присоединен к объекту #parent, и каждый раз, когда событие щелчка всплывает до него, возникшего на #child, оно запускает ваш обработчик щелчка.Это называется обработкой делегированных событий (обработка событий делегируется родительскому объекту).

Это сделано так, потому что вы можете прикрепить событие к объекту #parent, даже если объект #child не существуетпока, но когда он позже существует и щелкается, событие click будет всплывать до объекта #parent, оно будет видеть, что оно возникло на #child, и есть обработчик события для щелчка на #child и запускаетсяваше событие.

32 голосов
/ 06 января 2012

Попробуйте это:

$('#parent').on('click', '#child', function() {
    // Code
});

Из документации $.on():

Обработчики событий привязаны только к выбранным в данный момент элементам; Oни должен существовать на странице в тот момент, когда ваш код выполняет вызов .on().

Ваш элемент #child не существует, когда вы вызываете $.on(), поэтому событие не связано (в отличие от $.live()). #parent, однако, существует , так что связывание события с этим прекрасно.

Второй аргумент в моем коде выше действует как «фильтр», который срабатывает, только если событие всплыло до #parent с #child.

20 голосов
/ 06 января 2012

$(document).on('click', '#selector', function() { /* do stuff */ });

РЕДАКТИРОВАТЬ: Я предоставляю немного больше информации о том, как это работает, потому что ... слова.В этом примере вы размещаете слушателя на весь документ.

Когда вы click на любом элементе (ах), соответствующих #selector, событие всплывает до основного документа - до тех пор, пока нет других слушателей, которые вызывают метод event.stopPropagation() - что приведет квсплывающее событие для родительских элементов.

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

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

11 голосов
/ 06 января 2012

Эквивалент .live () в 1.7 выглядит так:

$(document).on('click', '#child', function() ...); 

По сути, просмотрите документ на наличие событий щелчка и отфильтруйте их для # child.

9 голосов
/ 07 мая 2014

Я знаю, что уже немного поздно для ответа, но я создал polyfill для метода .live (). Я протестировал его в jQuery 1.11, и, похоже, он работает довольно хорошо. Я знаю, что мы должны реализовывать метод .on () везде, где это возможно, но в больших проектах, где невозможно преобразовать все вызовы .live () в эквивалентные вызовы .on () по любой причине, может произойти следующее работа:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

Просто включите его после загрузки jQuery и перед вызовом live ().

5 голосов
/ 06 января 2012

.on () для jQuery версии 1.7 и выше.Если у вас более старая версия, используйте это:

$("#SomeId").live("click",function(){
    //do stuff;
});
3 голосов
/ 30 июля 2013

Я использовал «live» в своем проекте, но один из моих друзей предложил мне использовать «on» вместо live. И когда я попытался использовать это, у меня возникла такая же проблема, как у вас.

На своих страницах я динамически создаю строки таблиц кнопок и многие другие вещи. но когда я использую магию исчезла.

Другие решения, такие как использование, как ребенок, просто вызывает ваши функции каждый раз при каждом нажатии. Но я нахожу способ сделать это снова, и вот решение.

Введите свой код как:

function caller(){
    $('.ObjectYouWntToCall').on("click", function() {...magic...});
}

Вызов вызывающего абонента (); после того, как вы создадите свой объект на странице, как это.

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();

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

...