Как заставить JavaScript работать в ответ на кнопки, добавленные позже AJAX способом - PullRequest
2 голосов
/ 22 февраля 2012

У меня есть форма для отправки сообщения.Я хотел бы представить в AJAX способ.следующий код работает, но недавно добавленная кнопка «ответить» не работает:

      {% block body %}
<script type="text/javascript" src="{{ url_for('static', filename='jquery.form.js') }}"></script>
<script type="text/javascript">
    // wait for the DOM to be loaded
    $(document).ready(function () {
        $("#message_form").ajaxForm(function () {
            var messageid = '';
            var messagepubdate = 0;
            // GET NEWEST MESSAGE ID
            $.getJSON($SCRIPT_ROOT + '/_get_new_message', function (data) {
                messageid = data.messageid;
                messagepubdate = data.messagepubdate;
                //alert(messageid); //TESTED! the messageid is the newly added message's _id!
                var div = document.createElement("div");
                div.innerHTML = "<li><img src='{{ g.get_user(g.user._id).email|gravatar(size=48)}}'><p> " +
                 "<strong><a href='{{url_for('user_timeline', username=g.user._id)}}'>{{ g.user._id}}</a></strong>&nbsp; " + $('#new_message').val()
                 + "<small>&mdash; " + messagepubdate + "</small><p align='right' style='text-align: right'><small><a href='#' data-messageid='#replies" + messageid + "' class='reply'>Reply</a></small></p><p><br /><div class='replies hidden' id='replies" + messageid + "'></div></p></p></li>";
                $('ul#messages').prepend(div);
            });
            return false;
        });
    });
</script>

для старых сообщений, следующие скрипты хорошо работают для переключения ответов div:

<script type=text/javascript>
    $(function () {
        $('a.reply').click(function () {
            messageid = $(this).attr('data-messageid');
            $(messageid).text('loading');
            $.getJSON($SCRIPT_ROOT + '/_get_replies', { messageid: messageid.substring(8) }, function (data) {
                $(messageid).html(data.result);
                $(messageid).slideToggle(0);
            });
            return false;
        });
    });
</script>

Ответы [ 4 ]

3 голосов
/ 22 февраля 2012

Официальный ответ jQuery 1.7: jQuery.on.

Вы можете использовать jQuery.on, чтобы подписаться на любое событие, и вы можете использовать jQuery.offотменить подписку.

Чтобы прослушать все клики для элемента, соответствующего a.reply, независимо от того, когда он был добавлен в документ, вы можете использовать следующий код:

$(document.body).on('click', 'a.reply', function() { /* ... */ });

Аналогично, вы можете использовать

$('body').on('click', 'a.reply', function() { /* ... */ });

По сути, $('body') - это контекст , к которому добавляется прослушиватель событий.Таким образом, в действительности jQuery ожидает, пока любое событие не всплывет до элемента body, и проверяет, является ли это событие событием click.Если это так, а элемент, который создал событие click, соответствует селектору a.reply, то jQuery запустит делегат, который вы передали в качестве третьего параметра.

Если мы только что сделали это:

$('a.reply').on('click', function() { /* ... */ });

Это будет работать так же, но только прослушивает события, сгенерированные элементами , изначально выбранными при выборе a.reply.Поэтому любые новые элементы, добавленные в dom впоследствии, не будут включены.И поскольку мы не добавили селектор в метод on, он не будет прослушивать дочерние события.

Редактировать

В предыдущих версиях jQuery,вы бы использовали jQuery.live, который работает аналогичным образом, если не точно так же.В jQuery 1.7 jQuery.live просто переносится jQuery.on.

2 голосов
/ 22 февраля 2012

Если вам нужно прикрепить события к элементам, которые могут быть добавлены в будущем (через Ajax), вам всегда следует использовать делегирование событий.

Проще говоря, он работает, прикрепляя событие к родительскому элементу, а затем проверяя, какой дочерний элемент был нажат.Не имеет значения, добавлены или удалены дочерние элементы.

Правильный способ использования делегирования в jQuery - методы .on () и .off ():

$("#dataTable tbody").on("click", "tr", function(event){
    alert($(this).text());
}); 

.live () и делегат () устарели в пользу этого нового синтаксиса.

Фактически, jQuery теперь просто передает вызовы этих функций напрямую в .on () и .off ()

live: function( types, data, fn ) {
        jQuery( this.context ).on( types, this.selector, data, fn );
        return this;
    }

delegate: function( selector, types, data, fn ) {
        return this.on( types, selector, data, fn );
    }

Примечание. Это полезно не только в приложениях Ajax.Например, если у вас есть таблица с 1000 строками, гораздо эффективнее использовать делегированное событие в самой таблице, чем присоединять ее к сотням элементов

Некоторое дальнейшее чтение:

1 голос
/ 22 февраля 2012

Элементы, добавленные в DOM, должны иметь прикрепленные обработчики событий.Вам нужно присоединить их ПОСЛЕ вашего AJAX-вызова или заранее, используя функции jQuery .on() или .live().

1 голос
/ 22 февраля 2012

Вы захотите использовать функцию live() и передать click в качестве события для обработки.

.click() применяется ко всем объектам, которые существуют в настоящее время

.live()применяется ко всем текущим и будущим объектам.

$('a.reply').live( 'click' , function (e){ ... } );

Подробнее: http://api.jquery.com/live/

ОБНОВЛЕНИЕ

Как указали другие, live() устарела, и вы должны использовать on()

http://api.jquery.com/on/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...