Главная страница   /   9.2. Выполнение актуальной привязки событий (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

9.2. Выполнение актуальной привязки событий

Одним ограничением метода bind является то, что ваши функции обработки событий не связаны ни с одним новым элементом, который вы добавляете в DOM. В листинге 9-11 представлен пример.

Листинг 9-11: Добавление элементов после настройки обработчиков событий
<script type="text/javascript">
	$(document).ready(function () {
		$('img').bind({
			mouseenter: function () {
				$(this).css("border", "thick solid red");
			},
			mouseout: function () {
				$(this).css("border", "");
			}
		});

		$('#row1').append($("<div class='dcell'/>")
			.append("<img src='lily.png'/>")
			.append("<label for='lily'>Lily:</label>")
			.append("<input name='lily' value='0' required />"));
	});
</script>

В этом скрипте я использую метод bind, чтобы настроить обработчики для событий mouseenter и mouseout для всех элементов img. Затем я использую метод append, чтобы вставить в документ несколько новых элементов, включая другой элемент img. Этот новый элемент img не существовал, когда я использовал метод img, и мои функции обработчиков не связаны с ним. В результате этого у меня есть шесть элементов img, которые отображают рамку, когда мышка по ним двигается, и один, который не отображает.

В таком простом примере, как этот, простым решением был бы новый вызов метода bind, но это может вызвать сложности в отслеживании того, какие обработчики требуются для различных типов элементов. К счастью, jQuery облегчает нам эту задачу, предлагая набор методов, которые автоматически регистрируют обработчики событий, когда новые элементы, подходящие селектору, добавляются в DOM. Эти методы описаны в таблице 9-4.

Таблица 9-4: Методы для автоматической регистрации обработчиков событий
Метод Описание
live(eventType, function)
live(eventType, data, function)
live(map)
Добавляет сейчас или в дальнейшем обработчик события для элемента, который соответствует селектору jQuery
die() Удаляет всех обработчиков, созданных при помощи метода live
die(eventType) Удаляет обработчиков, созданных при помощи метода live, для указанных типов событий
delegate(selector, eventType, function)
delegate(selector, eventType, data, function)
delegate(selector, map)
Добавляет обработчик событий элементам, которые соответствуют селектору (сейчас или в дальнейшем), привязанному к элементам в объекте jQuery
undelegate()
undelegate(selector, eventType)
Удаляет обработчиков событий, созданных при помощи метода delegate, для указанных типов событий

В листинге 9-12 показан предыдущий обновленный пример с использованием метода live. Изменение незначительное, но привело к существенному результату. Любому элементу, соответствующему селектору img, который я добавлю в DOM, автоматически будет добавлена указанная функция обработки событий.

Совет

Метод live на самом деле не требует добавления функции обработки напрямую элементу. В действительности он просто создает обработчик событий объекта document и ищет события, которые были запущены элементами, подходящими селектору. Когда он замечает такое событие, он запускает обработчик. Все же с чисто практической точки зрения проще представить, что метод live старательно добавляет обработчики новым элементам.

Листинг 9-12: Использование метода live
<script type="text/javascript">
	$(document).ready(function () {
		$('img').live({
			mouseenter: function () {
				$(this).css("border", "thick solid red");
			},
			mouseout: function () {
				$(this).css("border", "");
			}
		});
		$('#row1').append($("<div class='dcell'/>")
			.append("<img src='lily.png'/>")
			.append("<label for='lily'>Lily:</label>")
			.append("<input name='lily' value='0' required />"));
	});
</script>

В этом примере новый добавленный элемент img соответствует селектору объекта jQuery, который я использовал с методом live, и становится связанным с обработчиками для событий mouseenter и mouseout.

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

Листинг 9-13: Использование метода die
<script type="text/javascript">
	$(document).ready(function () {
		$('img').live({
			mouseenter: function () {
				$(this).css("border", "thick solid red");
			},
			mouseout: function () {
				$(this).css("border", "");
			}
		});
		$('img').die();
	});
</script>

Внимание

Важно использовать одинаковый селектор с методами live и die; иначе метод die не отменит действия live.

Ограничение продвижения по DOM для действующих обработчиков событий

При использовании метода live возникает одна проблема – события должны распространиться по всему элементу document, прежде чем будут выполнены функции обработки. Можно определить более конкретный подход в решении этой задачи, если использовать метод delegate, который позволяет указать, где в документе должен быть расположен слушатель события. В листинге 9-14 представлен пример.

Листинг 9-14: Использование метода delegate
<script type="text/javascript">
	$(document).ready(function () {
		$('#row1').delegate("img", {
			mouseenter: function () {
				$(this).css("border", "thick solid red");
			},
			mouseout: function () {
				$(this).css("border", "");
			}
		});

		$('#row1').append($("<div class='dcell'/>")
			.append("<img src='carnation.png'/>")
			.append("<label for='carnation'>Carnation:</label>")
			.append("<input name='carnation' value='0' required />"));

		$('#row2').append($("<div class='dcell'/>")
			.append("<img src='lily.png'/>")
			.append("<label for='lily'>Lily:</label>")
			.append("<input name='lily' value='0' required />"));
	});
</script>

В этом примере я использую метод delegate, чтобы добавить слушатель элементу, чей id равен row1, а указанный мной селектор соответствует элементу img. В результате этого мои функции обработки будут выполнены, когда событие mouseenter или mouseout, которое произошло от элемента img, передастся элементу row1. Когда я добавляю другой элемент img в row1, он автоматически соотносится с вызовом метода delegate; и этого не происходит, если я добавляю элементы в row2.

Главным преимуществом метода delegate является скорость, о которой может стать вопрос, если ваш документ очень большой и сложный и в нем присутствуют много обработчиков событий. Если вы определите точку, от которой события будут распространяться вниз по документу, вы уменьшите расстояние, которое события вынуждены пройти по DOM, прежде чем это приведет к вызову функций обработки.

Совет

Чтобы удалить обработчики, добавленные при помощи метода delegate, нужно использовать undelegate. Метод die работает только с методом live.