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

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

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

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

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

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

или

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

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

Спасибо.

Ответ 1

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

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

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

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

Ответ 2

Попробуйте следующее:

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

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

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

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

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

Ответ 3

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

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

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

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

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

EDIT:

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

Ответ 4

Эквивалент .live() в 1.7 выглядит следующим образом:

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

В принципе, просмотрите документ для событий кликов и отфильтруйте их для #child.

Ответ 5

Я знаю, что немного опоздал на ответ, но я создал 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().

Ответ 6

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

$("#SomeId").live("click",function(){
    //do stuff;
});

Ответ 7

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

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

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

Напишите свой код как:

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

Call caller(); после создания вашего объекта на странице следующим образом.

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

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