Выбор динамически добавляемых элементов по имени класса - PullRequest
0 голосов
/ 19 марта 2020

У меня есть HTML код, который для простоты выглядит следующим образом:

<div class="main-container">
    <div class="group-area group1" id="group1">
        <select class="slct" id="slct1">
            <option>Group A</option>
            <option>Group B</option>
            <option>Group C</option>
        </select>
        <div class="participant-area">
            <!-- empty, can be filled with "<div class='participant'></div>" elements -->
        </div>
    </div>
    <button class="add-group">Show another group</button>
</div>

В приведенном выше интерфейсе пользователь может выбрать имя группы из выпадающего списка и участников этой группы будет отображаться в «зоне участников». Они будут извлечены из предварительно сохраненного списка и будут добавлены с помощью jQuery append:

<script>
    $(document).on('change', '.slct', function() {
                var number = $(this).attr("id").charAt(4); //gets the number '1' from the id name
                var key = $(this).find("option:selected").val(); //gets the value to be used later
                var constructedClass = ".group" + number; //result: "group1" 
                presavedList.forEach(participant => {
                        $(constructedClass + " .participant-area") //selecting participant area that is inside group1
                            .append($("<div>").addClass("participant")
                                .append($("<h2>").text(participant.name))
                            );
                    }


                })

</script>

Однако пользователь также может нажать кнопку «добавить группу» в конце основного контейнера, и отобразить другую область, аналогичную первой, которую можно использовать для просмотра участников другой группы. Но на этот раз классы будут group2 вместо group1, slct2 вместо slct1 и так далее. Это достигается с помощью глобальной переменной, которая увеличивается при каждом нажатии кнопки:

<script>
    var areaNumber = 1;
   $(".add-group").click(function () {
       areaNumber++;

       $(".main-container")
           .append($("<div>").addClass( "group"+areaNumber).addClass("group-area").attr("id", "group"+ areaNumber)
                   .append($("<select>")) //etc... Reconstruct the same one as original
                    .append($("<div>"))   //etc... Reconstruct the same one as original                    
   });
</script>

Моя проблема связана с выбором класса groupN динамически создаваемых элементов (таких как group2, group3, et c) , В первой функции выше - после создания второй области и изменения ее значения выбора - изменение обнаруживается нормально и $ (document) .on ('change', '.slct', function () {... }) увольняется нормально. Однако 5-я строка в этой функции:

$(constructedClass + " .participant-area").append(//etc)

не работает: функция construclass не обнаруживается функцией, даже если она существует во время ее запуска, но я считаю, что она не обнаруживается потому что он не присутствовал во время начального анализа javascript. Это верно? Есть ли способ решить это? (Уметь выбирать динамически сгенерированные элементы по их уникально сгенерированным именам классов?).

Спасибо за прочтение и за любую помощь, которую вы можете предложить.

1 Ответ

1 голос
/ 19 марта 2020

Не используйте добавочные атрибуты id и class . Это анти-паттерн. Это делает ваш код излишне сложным, более подробным и трудным в обслуживании.

Гораздо лучшим решением является группировка общих элементов по поведению с использованием одного атрибута class. Таким образом, вы можете использовать обход DOM, чтобы связать их друг с другом. Он также позволяет clone() контенту (поскольку он все идентичен) без необходимости спагеттировать ваш JS, заполнив его HTML.

. С учетом сказанного попробуйте следующее:

let presavedList = [{ name: 'Foo bar' }, { name: 'Lorem ipsum' }]

$(document).on('change', '.slct', function() {
  var html = presavedList.map(item => `<div class="participant"><h2>${item.name}</h2></div>`);
  $(this).next('.participant-area').html(html);
});

$(".add-group").click(function() {
  var $clone = $('.group:first').clone();
  $clone.find('select').val('');
  $clone.find('.participant-area').empty();
  $clone.appendTo('.main-container');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-container">
  <div class="group-area group">
    <select class="slct">
      <option value="">Please select...</option>
      <option>Group A</option>
      <option>Group B</option>
      <option>Group C</option>
    </select>
    <div class="participant-area"></div>
  </div>
  <button class="add-group">Show another group</button>
</div>
...