繁体   English   中英

如何将动态创建的按钮单击事件绑定到 javascript 中动态创建的输入?

[英]how to bind dynamically created button click events to dynamically created input in javascript?

我对 javascripts 非常陌生,并试图创建一个动态 html 表单,其中有多个按钮,每个按钮单击 map 到相应的表单输入。 这是我的代码:

<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>`

因此,用户将输入要创建的组数并单击“开始”按钮,然后代码应使用用户选择的数字动态生成表单。 每组表单都包括一个输入文本框和一个“生成”按钮。 单击按钮时,输入文本框将显示“hello world”。 但是,无论我单击哪个“生成”按钮,“hello world”都只会显示在最后一个输入文本框中。 所以我将按钮的 onclick function 更改为:

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

然后我发现无论我单击哪个“生成”按钮, thisID始终是最后一个输入文本框的 id。 我猜这是因为单击事件的绑定直到脚本完成时才会发生,而“thisID”始终是其最新值。

有人可以帮我实现我想要的功能吗? 非常感谢!

您需要将 for 循环中的代码包装在单独的 function 中,并将 i 的值作为参数传递。 这将创建一个闭包,为您的代码创建一个新的执行 scope。 否则发生的事情是您的 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 将变量范围限定为当前代码块,而不是提升到 function 的 scope,因此每个 for 循环迭代都有一个私有 let 变量。 但是,仍然建议您对闭包及其工作方式有一个很好的了解。

由于您已经在使用 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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM