В jQuery, как прикрепить события к динамическим элементам html? [дубликат]
этот вопрос уже есть ответ здесь:
Предположим, у меня есть некоторый код 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.
8 ответов:
я добавляю новый ответ, чтобы отразить изменения в более поздних выпусках jQuery. Этот.метод live () устарел с jQuery 1.7.
от http://api.jquery.com/live/
по состоянию на jQuery 1.7, the .жить() метод является устаревшим. Использовать.on () для присоединения обработчиков событий. Пользователи более старых версий jQuery использовать .делегат() в предпочтении к.жить.)(
для jQuery 1.7+ вы можете прикрепить обработчик событий к родительскому элементу с помощью .on (), и передать селектор a в сочетании с "myclass" в качестве аргумента.
Так вместо...
$(".myclass").click( function() { // do something });вы можете писать...
$('body').on('click', 'a.myclass', function() { // do something });Это будет работать для всех тегов с "myclass" в теле, будь то уже присутствует или динамически добавляется позже.
тег body используется здесь, поскольку в Примере не было более близкого статического окружающего тега, но любой родительский тег, который существует, когда .по методам вызов происходит будет работать. Например, тег ul для списка, в который будут добавлены динамические элементы, будет выглядеть так:
$('ul').on('click', 'li', function() { alert( $(this).text() ); });пока существует тег ul, это будет работать (никаких элементов li еще не существует).
иногда делаю это (топ-проголосовали ответ) не всегда достаточно:
$('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 () и .выкл()
Шон показывает пример.
Рекомендуется:
используйте функции 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 }); });
вы можете привязать одно событие click к странице для всех элементов, независимо от того, находятся ли они уже на этой странице или если они прибудут в какое-то будущее время, например:
$(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 или любого другого метода делегирования событий, но.bind()до сих пор работает.
Если ваш на jQuery 1.3+, то используйте . live ()
привязывает обработчик к событию (как клик) для всех текущих и будущих - соответствующий элемент. Можно также привязать пользовательские события.
Comments