![](/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.