jQuery. Обработка событий на вновь созданных элементах.

Всем привет! Хочу рассказать сегодня о том, почему обработчики могут не обрабатывать события и как правильно действовать в таких случаях. На самом деле все логично реализовано, просто надо четко осознать ситуацию, с которой сталкиваешься.Разбираться будем на примере события click, которое, как понятно из названия обрабатывает клик на элемент. Выделим два варианта обработчика: обработчик имеющегося элемента и обработчик созданного элемента(например в результате успешного ajax-запроса). Скажу сразу что будем разбираться с участками кода, думаю что как подключать jQuery рассказывать не надо.

Будем использовать следующий кусок html для разбора ситуаций:

<div class="testcontainer1">
	<a href="google.com">Нажми чтобы вывести!</a>
</div>
<div class="testcontainer2">
</div>

Два контейнера в одном из которых будет ссылка. Задача - считать адрес ссылки и вывести оно пользователю, при этом запретив переход по ссылке. Начнем.

Чтобы обработать клик по имеющейся ссылке нам подойдет такой код:

$('.testcontainer1 a').click(function(e){
	e.preventDefault(); //запрещаем переход по ссылке
	var adr = $(this).attr('href');
	alert(adr);
});

Этот код успешно отработает по клику на имеющейся ссылке, но если появится еще одна, то на ней он не сработает и все верно. Метод click навешивается только на имеющиеся компоненты! Чтобы обработать клик на новые компоненты, необходимо использовать метод on. Синтаксис его немного отличается но он довольно прост:

$(sel).on(events [, selector ] [, data ], handler)

events - события, одно или несколько, разделенные пробелами

selector - дополнительный селектор, который производит выборку из компонентов выбранных внешним селектором sel

data - данные для передачи в обработчик

handler - функция обработчик

Зная это, мы можем поправить нашу функцию:

$('.testcontainer1 a').on('click', function(e){
	e.preventDefault(); //запрещаем переход по ссылке
	var adr = $(this).attr('href');
	alert(adr);
});

Эта функция обработает клик даже на добавленные в контейнер testcontainer1 ссылки. Попробуем написать для второго контейнера:

$('.testcontainer2 a').on('click', function(e){
	e.preventDefault(); //запрещаем переход по ссылке
	var adr = $(this).attr('href');
	alert(adr);
});

Увы такой код не сработает. Причина проста. Контейнер был изначально пуст и поэтому обработчик не был навешен на элемент, потому что элемента не было. Но выход прост. Навесить события на сам контейнер. Если внимательно посмотреть на описание функции, то станет понятно, что это вовсе не проблема. Выглядеть это будет так:

$('.testcontainer2').on('click', 'a', function(e){
	e.preventDefault(); //запрещаем переход по ссылке
	var adr = $(this).attr('href');
	alert(adr);
});

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

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

Вот и все. Если будут вопросы, пишите. До новых встреч!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *