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

Новичок во всем этом, играя с Firebase. По сути, я хочу получить текстовые записи из Firebase и иметь рядом с ним кнопку «Подтвердить». Когда кнопка нажата, я хочу, чтобы эта конкретная текстовая запись была перемещена в новое местоположение 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();

});

person Sam    schedule 10.07.2013    source источник


Ответы (5)


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

$('#yourContainer').on('click', '#approve', function(){
    //your code here..
});
person Nikko Reyes    schedule 10.07.2013
comment
Чтобы расширить, первый аргумент on() — это событие, второй — селектор, который, если он присутствует, делегирует события дочерним элементам этого элемента, даже если они будут добавлены в будущем. - person Kato; 10.07.2013
comment
Это сработало для меня после того, как я потратил 3 с лишним часа на поиски этого хака! Вы, сэр, заслуживаете медали! - person juanchod; 03.10.2019
comment
Теперь, как вы это сделаете, если у вас есть куча ссылок, и вам нужно .каждую из них? - person gillespieza; 06.07.2021

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

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

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

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

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

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

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

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

person Shaheed Haque    schedule 01.07.2019
comment
$(document.getElementById(mynewthing))... с большой буквы i - person Kristoffer; 17.05.2021

Другая альтернатива, более простая для понимания, менее мощная, но также вполне допустимая, заключается в том, чтобы просто привязать событие во время создания элемента:

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'));
});
person Kato    schedule 10.07.2013
comment
Я не согласен с тем, что это проще для понимания, и кажется излишне сложным, когда правильное связывание команды .on() будет работать нормально. - person Colin R. Turner; 07.01.2019

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

$("#button").click(function(e){
   $(".parentContainer").find(".dynamically-child-element").html("Hello world");
});

Or

$(".parentContainer").find(".dynamically-child-element").html("Hello world"); // not in click event

Итак, это моя демонстрация

person QDinh    schedule 08.04.2020