![](/img/trans.png)
[英]How to bind on click event on dynamically created button in Angular 6?
[英]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.