Уроки JavaScript – не работают события jQuery после AJAX загрузки

Если вы используете AJAX на своем сайте, имейте в виду, что такие события, как клик (click), отправка (submit), наведение (hover), могут не работать, если вы не прикрепите их правильно. В сегодняшней статье мы рассмотрим практическое решение проблемы, когда не срабатывают события в jQuery после динамического изменения страницы (или AJAX).

 

 

Описание задачи

Допустим, у нас есть блоки с заголовком и скрытым контентом в теге <p>. По клику на заголовке, скрытый контент показывается/прячется с помощью функции toggle():

$('a.zagolovok').click(function(e){
  e.preventDefault();
  $(this).next('p').toggle();
});

 

Потом мы загружаем новые элементы (блоки) без перезагрузки страницы с помощью AJAX. Когда мы перезагружаем страницу – все работает нормально, но если новые элементы подгружаются AJAX’ом, — не работает функция toggle().

 

 

Вариант решения №1

Событие click прикрепляется к существующим элементам после полной загрузки страницы. Ключевое слово здесь – существующим. Когда мы загружаем что-то с помощью AJAX, мы манипулируем DOM. Мы размещаем абсолютно новый элемент, который не существовал при загрузке страницы. Поэтому нам нужно прикрепить это событие после подгрузки нового контента. Если вы используете функцию .load() (которая загружает данные с сервера и помещает возвращенный HTML в соответствующие элементы), вам просто нужно поместить функцию click() в функцию обратного вызова:

$('.blocks-wrapper').load(link.attr('href'), function(responseText, textStatus, XMLHttpRequest){
 $('a.zagolovok').click(function(e){
  e.preventDefault();
  $(this).next('p').toggle();
 });
});

 

Так мы прикрепляем событие click и к новым добавленным элементам.

Если вы используете функцию .ajax() вместо .load(), просто присоедините событие к функции .done() (которая добавляет обработчик, что будет вызываться при обработке отложенного объекта) AJAX вызова.

 

 

Вариант решения №2

Что делать, если мы не хотим прикреплять событие каждый раз, когда вызывается AJAX? Для этого есть другое, более «глобальное» решение. Мы можем использовать функцию .on().

Функция .click() похожа с .on('click'), но здесь есть одна важная часть – при второй функции мы можем делегировать событие. Преимущество делегированных событий заключается в том, что они могут обрабатывать события для элементов-потомков, которые добавляются в документ позднее (например, при AJAX).

Поэтому вместо того, чтобы прикреплять событие click к завершенному AJAX, мы просто добавляем его более «глобально»:

$('.blocks-wrapper').on('click', 'a.zagolovok', function(e){
  e.preventDefault();
  $(this).next('p').toggle();
});

 

Мы могли бы присоединить обработчик и к тегу <body>, но лучше прикреплять делегированные события как можно ближе к целевым элементам в документе. Нужно избегать чрезмерного использования document или document.body для делегированных событий на больших страницах с большим DOM.

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

В более ранних версиях jQuery вместо .on() использовались функции .live() (устарела с версии jQuery 1.9) или .delegate() (устарела с версии jQuery 3.0).

 

Recent Posts

Брюс Ли

Нет такой фразы "Я не могу!" Сумел один, смогут и другие. Не смог никто -… Read More

21/07/2021

Иоганн Вольфганг фон Гете

К чему душе беззлобье, широта уму, Руке готовность действовать и воля, Когда в горячке зла… Read More

12/07/2021

Какой бойлер использовать для кухни

Незаменимым устройством при отключении горячей воды является бойлер для кухни, позволяющий с комфортом мыть посуду… Read More

08/07/2021

Али ибн Абу Талиб

Лучше хранить молчание до тех пор, пока не спросят, чем говорить до тех пор, пока… Read More

07/07/2021

Мухаммад Окар

То, что вы имеете каждый день, кто-то ежедневно вымаливает Мухаммад Окар   Read More

01/07/2021

Конфуций

У человека есть три пути, чтобы разумно поступать: первый, самый благородный, — размышление; второй, самый… Read More

26/06/2021