Ответ 1
Предупреждение. Этот ответ старый. Все еще очень полезно, но
live
устарел и удален в новых версиях jQuery. Поэтому прочитайте ответ, потому что варианты использования не изменились, и вы узнаете, почему и когда использовать меньше обработчиков событий. Но если вы по-прежнему не используете действительно старую версию jQuery (v1.4.2 или ранее), вы должны подумать о написании нового эквивалентного кода. Как описано в jQuery API дляlive
и скопировано здесь:Переписывание метода
.live()
в терминах его преемников является простым; это шаблоны для эквивалентных вызовов для всех трех способов вложения событий:
$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+
Иногда у вас есть набор элементов, когда страница загружается, например, редактирует ссылки:
<table>
<tr>
<td>Item 1</td>
<td><a href="#" class="edit">Edit</a></td>
</tr>
<tr>
<td>Item 2</td>
<td><a href="#" class="edit">Edit</a></td>
</tr>
<tr>
<td>Item 3</td>
<td><a href="#" class="edit">Edit</a></td>
</tr>
</table>
Теперь, возможно, у вас есть что-то подобное с jQuery:
$(document).ready(function() {
$('a.edit').click(function() {
// do something
return false;
});
});
Но что, если вы добавите новый элемент в эту таблицу динамически, после того, как страница изначально загрузилась?
$('table').append('
<tr><td>Item 4</td><td><a href="#" class="edit">Edit</a></td></tr>
');
Когда вы нажимаете "Изменить" на этом новом элементе, ничего не произойдет, потому что события были связаны с загрузкой страницы. Введите вживую. С его помощью вы можете связать событие выше:
$(document).ready(function() {
$('a.edit').live('click', function() {
// do something
return false;
});
});
Теперь, если вы добавите новые элементы <a>
с классом edit
после первоначальной загрузки страницы, он все равно зарегистрирует этот обработчик событий.
Но как это достигается?
jQuery использует так называемую делегирование делегирования для достижения этой функциональности. Делегирование событий полезно в этой ситуации или когда вы хотите загрузить большое количество обработчиков. Скажем, у вас есть DIV с изображениями:
<div id="container">
<img src="happy.jpg">
<img src="sad.jpg">
<img src="laugh.jpg">
<img src="boring.jpg">
</div>
Но вместо 4 изображений у вас есть 100 или 200 или 1000. Вы хотите привязать событие клика к изображениям, чтобы действие X выполнялось, когда пользователь нажимает на него. Выполнение этого, как вы могли ожидать...
$('#container img').click(function() {
// do something
});
... затем привяжет сотни обработчиков, которые все сделают то же самое! Это неэффективно и может привести к низкой производительности в тяжелых веб-папках. При делегировании событий, даже если вы не планируете добавлять больше изображений позже, использование live может быть намного лучше для такого рода ситуаций, так как вы можете привязать обработчик один к контейнеру и проверить, когда он щелкнуть, если цель была изображением, а затем выполнить действие:
// to achieve the effect without live...
$('#container').click(function(e) {
if($(e.target).is('img')) {
performAction(e.target);
}
});
// or, with live:
$('img', '#container').live('click', function() {
performAction(this);
});
Так как jQuery знает, что новые элементы могут быть добавлены позже или что производительность важна, вместо привязки события к реальным изображениям, он может добавить его в div, как в первом примере (на самом деле, я довольно уверен, что он связывает их с телом, но может быть в контейнере в примере выше), а затем делегировать. Это свойство e.target
позволяет проверить его после того, как событие, которое было нажато/выполнено, соответствует указанному вами селектору.
Чтобы было ясно: это полезно не только для прямого перехода к событиям повторной записи, но для большого количества элементов это может быть значительно быстрее.