Предположим, у меня есть некоторый код 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
создается, когда пользователь нажимает на a#anchor1
.
Ссылка test4
не имеет обработчика click()
, даже если она имеет class="myclass"
.
По сути, я хотел бы написать обработчик click()
один раз, и он будет применяться как к контенту, присутствующему при загрузке страницы, так и к контенту, добавляемому позже через AJAX/DHTML. Любая идея, как я могу это исправить?
Ответ 1
Я добавляю новый ответ, чтобы отразить изменения в более поздних версиях jQuery. Метод .live() устарел из jQuery 1.7.
Из http://api.jquery.com/live/
Как и в jQuery 1.7, метод .live() устарел. Используйте .on() для присоединения обработчиков событий. Пользователи более старых версий jQuery должны использовать .delegate() в предпочтении .live().
Для jQuery 1.7+ вы можете присоединить обработчик события к родительскому элементу с использованием .on() и передать селектор в сочетании с "myclass" в качестве аргумента.
См. http://api.jquery.com/on/
Итак, вместо...
$(".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).
Ответ 2
Иногда выполнение этого (ответ на верхний голос) не всегда достаточно:
$('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();
}
Надеюсь, это поможет!
Привет,
Ответ 3
После jQuery 1.7 предпочтительными методами являются . on() и .off()
В ответе Шона показан пример.
Теперь устарела:
Используйте функции jQuery .live()
и .die()
. Доступно в jQuery 1.3.x
Из документов:
Чтобы отобразить текст каждого абзаца в при каждом щелчке:
$("p").live("click", function(){
alert( $(this).text() );
});
Кроме того, плагин livequery делает это и поддерживает больше событий.
Ответ 4
Если вы добавляете кучу привязок в DOM, обратите внимание на делегирование событий.
Вот простой пример:
$('#somecontainer').click(function(e) {
var $target = $(e.target);
if ($target.hasClass("myclass")) {
// do something
}
});
Ответ 5
Привязывает обработчик к событию (например, щелчок) для всех элементов, соответствующих текущему и будущему. Может также связывать пользовательские события.
текст ссылки
$(function(){
$(".myclass").live("click", function() {
// do something
});
});
Ответ 6
Вы можете привязать событие с одним кликом к странице для всех элементов, независимо от того, находятся ли они на этой странице или они появятся в будущем, например:
$(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()
все еще работает.
Ответ 7
Если вы используете jQuery 1.3+, live()
Привязывает обработчик к событию (например, клик) для всех текущих и будущих - согласованный элемент. Может также связывать пользовательские события.
Ответ 8
Вы хотите использовать функцию live()
. См. документы.
Например:
$("#anchor1").live("click", function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});