Выполнение актуальной привязки событий
Одним ограничением метода 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
.