Как связать динамически созданные события нажатия кнопки с динамически созданным вводом в JavaScript? - PullRequest
0 голосов
/ 14 октября 2019

Я очень плохо знаком с javascripts и пытаюсь создать динамическую HTML-форму, где есть несколько кнопок, и каждая кнопка кликает карту к соответствующей форме ввода. Вот мой код:

<html>
<head>
    <title>Create Group</title>
    <script src="/js/jquery-3.4.1.min.js"></script>

    <script>

        $(document).ready(function(){

            $("#generate_form").click(function(){
            var number = document.getElementById("number_of_groups").value;
            var container = document.getElementById("container");
            while (container.hasChildNodes()) {
                container.removeChild(container.lastChild);
            }
            var i;
            for (i=1;i<=number;i++){
                var p = document.createElement("p");
                var node = document.createTextNode("group " + i + " :");
                p.appendChild(node);
                container.appendChild(p);
                var input = document.createElement("input");
                input.type = "text";
                var thisID = 'group_'+i;
                input.id = thisID;
                input.name=thisID;
                container.appendChild(input);
                var button = document.createElement("button");
                button.id = "button_"+i;
                button.type = "button";
                container.appendChild(button);
                button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
                var buttonLabel = document.createTextNode("Generate");
                button.appendChild(buttonLabel);
                container.appendChild(document.createElement("br"));
            }
           })
        });
    </script>
</head>
<body>
    <h2>Create some group(s)</h2>
    <br>
    Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
    <button id="generate_form" type="button">GO</button>
    <div id="container"/>

</body>
</html>`

Таким образом, пользователь вводит количество групп для создания и нажимает кнопку «Перейти», затем код должен динамически генерировать форму с номером, выбранным пользователем. Каждая группа формы включает в себя текстовое поле ввода и кнопку «Создать». Когда кнопка нажата, текстовое поле ввода покажет «Привет мир». Однако «Привет мир» отображается только в последнем текстовом поле ввода независимо от того, какую кнопку «Создать» я нажимаю. Таким образом, я изменил функцию нажатия кнопки на:

button.onclick = function(){ alert(thisID);};

Затем я обнаружил, что thisID всегда является идентификатором последнего текстового поля ввода независимо от того, какую кнопку «Создать» я нажимаю. Я предполагаю, что это связано с тем, что привязка события click не происходит до тех пор, пока сценарий не будет выполнен, когда «thisID» всегда будет иметь последнее значение.

Кто-нибудь может помочь мне реализовать желаемую функциональность? Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Поскольку вы уже используете JQuery, вы можете уменьшить некоторую логику. Дайте мне знать, если это поможет -

<html>
    <head>
        <title>Create Group</title>
    </head>
    <script src="/js/jquery-3.4.1.min.js"></script>
    <script>
        $(document).ready(()=>{

        var txtGroup='<input type="text" id="txt_group_{0}" value="">';
        var btnGroup='<button id="btn_group_{0}" type="button">Click Me</button>';
        var container=$('#container');

        $('#generate_form').click((e)=>{
            var groupCount=parseInt($('#number_of_groups').val());
            var idToStart=$('#container').children('div').length+1;
            for(let i=idToStart;i< idToStart+groupCount;i++){
                var divGroup=`<div id="div_group_${i}">`+
                txtGroup.replace('{0}',i)+
                btnGroup.replace('{0}',i)+`</div>`;

                container.append(divGroup);
                $('#btn_group_'+i).on('click',(e)=>{
                    console.log('#txt_group_'+i);
                    $('#txt_group_'+i).val('Hello World');
                });
            }

        });

    });
    </script>
    <body>
        <h2></h2>
        <br>
        Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
        <button id="generate_form" type="button">GO</button>
        <div id="container"></div>
    </body>
    </html>
0 голосов
/ 14 октября 2019

Вам нужно будет обернуть код внутри цикла for в отдельную функцию, передав значение i в качестве параметра. Это создаст замыкание, создав новую область выполнения для вашего кода. В противном случае происходит то, что ваш var поднимается и не является эксклюзивным для каждой итерации цикла for, поэтому ваш DOM отражает только последнее присвоенное ему значение.

for (i=1;i<=number;i++){
  (function (i) {
    var p = document.createElement("p");
    var node = document.createTextNode("group " + i + " :");
    p.appendChild(node);
    container.appendChild(p);
    var input = document.createElement("input");
    input.type = "text";
    var thisID = 'group_'+i;
    input.id = thisID;
    input.name=thisID;
    container.appendChild(input);
    var button = document.createElement("button");
    button.id = "button_"+i;
    button.type = "button";
    container.appendChild(button);
    button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
    var buttonLabel = document.createTextNode("Generate");
    button.appendChild(buttonLabel);
    container.appendChild(document.createElement("br"));
  })(i);
}

Вы можете проверитьстатья о замыканиях здесь: https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

РЕДАКТИРОВАТЬ: Как упомянул один из ваших комментаторов, вы также можете установить свои переменные «позволить» для достижения аналогичного эффекта. Это связано с тем, что let определяет область действия для текущего блока кода, а не перемещается в область действия функции, поэтому каждая итерация цикла имеет частную переменную let. Тем не менее, все же рекомендуется получить хорошее представление о замыканиях и о том, как они работают.

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