Предположим, что у меня есть код jQuery, который прикрепляет обработчик событий ко всем элементам с классом "myclass" . Например:
$(function(){
$(".myclass").click( function() {
// do something
});
});
И мой html может быть следующим:
<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>
Это работает без проблем. Однако подумайте, были ли элементы "myclass" написаны на странице в будущем.
Например:
<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
$("#anchor1").click( function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
});
</script>
В этом случае ссылка "test4" создается, когда пользователь нажимает на # anchor1.
В ссылке "test4" нет связанного с ним обработчика click(), хотя он имеет class= "myclass" .
Любая идея, как я могу это исправить?
В принципе, я хотел бы написать обработчик click() один раз и применить его как к содержимому, содержащемуся при загрузке страницы, так и к контенту, добавленному позже через Ajax/DHTML.
Я добавляю новый ответ, чтобы отразить изменения в более поздних версиях jQuery. Метод .live() устарел из jQuery 1.7.
Из http://api.jquery.com/live/
Как и в jQuery 1.7, метод .live() устарел. Используйте .on() для присоединения обработчиков событий. Пользователи более старых версий jQuery должны использовать .delegate() в предпочтении .live().
Для jQuery 1.7+ вы можете присоединить обработчик события к родительскому элементу с использованием .on() и передать селектор в сочетании с "myclass" в качестве аргумента.
Итак, вместо...
$(".myclass").click( function() {
// do something
});
Вы можете написать...
$('body').on('click', 'a.myclass', function() {
// do something
});
Это будет работать для всех тегов с "myclass" в теле, уже присутствующих или динамически добавленных позже.
Тег тела используется здесь, поскольку в примере не было более тесного окружающего тега, но любой родительский тег, который существует при вызове метода .on, будет работать. Например, тег ul для списка, в который будут добавлены динамические элементы, будет выглядеть так:
$('ul').on('click', 'li', function() {
alert( $(this).text() );
});
Пока существует тег ul, это будет работать (еще нет элементов li).
$('selector').on('event', callback(){})
это не сработает. Нужно написать нужный селектор внутри на (). $(document).on('event', 'selector', callback(){})
или, $('body').on('event', 'selector', callback(){})
Иногда выполнение этого (ответ на верхний голос) не всегда достаточно:
$('body').on('click', 'a.myclass', function() {
// do something
});
Это может быть проблема из-за того, что обработчики событий заказа запущены. Если вы обнаружите, что делаете это, но это вызывает проблемы из-за порядка, в котором он обрабатывается. Вы всегда можете перенести это в функцию, которая при вызове "обновляет" слушателя.
Например:
function RefreshSomeEventListener() {
// Remove handler from existing elements
$("#wrapper .specific-selector").off();
// Re-add event handler for all matching elements
$("#wrapper .specific-selector").on("click", function() {
// Handle event.
}
}
Поскольку это функция, всякий раз, когда я настраивал свой слушатель таким образом, я обычно называю его готовым к документу:
$(document).ready(function() {
// Other ready commands / code
// Call our function to setup initial listening
RefreshSomeEventListener();
});
Затем, всякий раз, когда вы добавляете некоторый динамически добавленный элемент, снова вызовите этот метод:
function SomeMethodThatAddsElement() {
// Some code / AJAX / whatever.. Adding element dynamically
// Refresh our listener, so the new element is taken into account
RefreshSomeEventListener();
}
Надеюсь, это поможет!
Привет,
После jQuery 1.7 предпочтительными методами являются . on() и .off()
В ответе Шона показан пример.
Используйте функции jQuery
.live()
и.die()
. Доступно в jQuery 1.3.xИз документов:
Чтобы отобразить текст каждого абзаца в при каждом щелчке:
$("p").live("click", function(){ alert( $(this).text() ); });
Кроме того, плагин livequery делает это и поддерживает больше событий.
Если вы добавляете кучу привязок в DOM, обратите внимание на делегирование событий.
Вот простой пример:
$('#somecontainer').click(function(e) {
var $target = $(e.target);
if ($target.hasClass("myclass")) {
// do something
}
});
Привязывает обработчик к событию (например, щелчок) для всех элементов, соответствующих текущему и будущему. Может также связывать пользовательские события.
$(function(){
$(".myclass").live("click", function() {
// do something
});
});
live
не рекомендуется.
Вы можете привязать событие с одним кликом к странице для всех элементов, независимо от того, находятся ли они на этой странице или они появятся в будущем, например:
$(document).bind('click', function (e) {
var target = $(e.target);
if (target.is('.myclass')) {
e.preventDefault(); // if you want to cancel the event flow
// do something
} else if (target.is('.myotherclass')) {
e.preventDefault();
// do something else
}
});
Использовал его некоторое время. Работает как шарм.
В jQuery 1.7 и более поздних версиях рекомендуется использовать .on()
вместо связывания или любого другого метода делегирования событий, но .bind()
все еще работает.
Если вы используете jQuery 1.3+, live()
Привязывает обработчик к событию (например, клик) для всех текущих и будущих - согласованный элемент. Может также связывать пользовательские события.
Вы хотите использовать функцию live()
. См. документы.
Например:
$("#anchor1").live("click", function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});