JQuery: выбор динамически созданных элементов и нажатие на Firebase

Начинающий все это, играя с Firebase. В принципе, я хочу получить текстовые записи из Firebase и нажать кнопку "Approve" рядом с ним. Когда кнопка нажата, я хочу, чтобы конкретная текстовая запись была перенесена в новое местоположение Firebase и текст удален со страницы. Я создаю кнопку и текст динамически, и у меня возникают проблемы с выбором кнопки и созданных мной div. Я знаю, что мне нужно использовать on(), но я не уверен, как его использовать.

Спасибо!

approveRef.on('child_added', function(snapshot) {
 var posts = snapshot.val();
 $('<div id="post">').text(posts.text).append('<button style ="button" id="approve">Approve</button>').appendTo($('#feed'));
});

$('#approve').on("click", function(){
    var text = $('#post').val();
    postsRef.push({'text':text});
    $('#post').remove();

});

Ответ 1

Вам нужно привязать .on() к контейнеру вашего динамически добавленного элемента, который уже находится на странице при его загрузке, и иметь следующее:

$('#yourContainer').on('click', '#approve', function(){
    //your code here..
});

Ответ 2

Ваш .on() не работает, потому что вы добавляете кнопку динамически. Вы не можете найти динамически добавленные элементы напрямую, используя этот селектор идентификатора элемента, например $('#approve'). Поэтому вы должны связать .on() с помощью селектора $(document). Это всегда будет содержать ваши динамически добавленные элементы.

$(document).on( eventName, selector, function(){} );

$(document).on('click','#approve',function(){
//your code here
});

Ответ 3

Еще одна альтернатива, более простая для понимания, менее мощная, также совершенно правильная, - просто привязать событие при создании элемента:

approveRef.on('child_added', function(snapshot) {
 var posts = snapshot.val();
 var $button = $('<button style ="button" id="approve">Approve</button>');
 $button.on("click", function(){
    var text = $('#post').val();
    postsRef.push({'text':text});
    $('#post').remove();
 });

 $('<div id="post">').text(posts.text).append($button).appendTo($('#feed'));
});

Еще одна проблема, с которой вы столкнетесь, предполагая, что на странице будет более одного, заключается в том, что вы используете идентификаторы в записях. Они будут сталкиваться, если они не уникальны.

Отличной альтернативой является обращение к этим элементам с помощью тегов data- * или других идентифицирующих признаков, таких как теги css. Но в вашем случае они вам вообще не нужны!

approveRef.on('child_added', function(snapshot) {
 var posts = snapshot.val();
 var id = snapshot.name();

 var $button = $('<button style="button">Approve</button>');
 $button.on("click", function(){
    // use parent.closest(...) in place of an ID here!
    var text = $(this).parent().closest('textarea').val();
    postsRef.push({'text':text});
    $(this).parent().remove();
 });

 /* just an example of how to use a data-* tag; I could now refer to this element using:
    $('#feed').find('[data-record="'+id+'"]') if I needed to find it */
 $('<div data-record="'+id+'">').text(posts.text).append($button).appendTo($('#feed'));
});

Ответ 4

Я нахожу быстрое погружение в DOM, а затем возвращаюсь в jQuery, что очень удобно для этой проблемы:

// Construct some new DOM element.
$(whatever).html('... id="mynewthing"...');

// This won't work...
$("#mynewthing")...

// But this will...
$(document.getElementByid("mynewthing"))...

Это работает, превращая объект DOM непосредственно в селектор. Мне это нравится, потому что подход прозрачен в работе/намерении.