Javascript 单击动态创建的表行复选框上未触发的事件

Javascript 单击动态创建的表行复选框上未触发的事件,javascript,html,events,onclick,Javascript,Html,Events,Onclick,我有一个用行动态填充的表,其中一列有复选框,可以切换该特定行的相关属性 问题是,我添加到复选框中的单击事件仅在页面加载时触发-当页面刷新时,控制台生成3行“False”。如果在此之后我选中/取消选中复选框,则控制台没有输出,因此我假设事件不是在单击时触发的 我不希望它在页面加载时触发,我希望它在单击复选框时触发 下面是产生问题的代码的简化版本 index.html: <html> <head> <script src="main.js">&

我有一个用行动态填充的表,其中一列有复选框,可以切换该特定行的相关属性

问题是,我添加到复选框中的单击事件仅在页面加载时触发-当页面刷新时,控制台生成3行“False”。如果在此之后我选中/取消选中复选框,则控制台没有输出,因此我假设事件不是在单击时触发的

我不希望它在页面加载时触发,我希望它在单击复选框时触发

下面是产生问题的代码的简化版本

index.html:

<html>
<head>
<script src="main.js"></script>
</head>
<body>
<table id="table">
<thead><tr><th scope="col">Toggled</th></tr></thead>
<tbody></tbody>
</table>
</div>
</body>
</html>

切换
main.js:

document.addEventListener('DOMContentLoaded', () => {
    AddRow(0);
    AddRow(1);
    AddRow(2);
    
    function AddRow(i) {
        var table = document.getElementById('table');
        var tbody = table.getElementsByTagName('tbody')[0];
        
        var node = document.createElement("tr");
        node.setAttribute("id", i);
        node.innerHTML = `<td><input id='T${i}' type='checkbox' /></td>`;
        tbody.appendChild(node);
        document.getElementById(`T${i}`).addEventListener('click', Toggle(i));
    }
    
    function Toggle(i) {
        if (document.getElementById(`T${i}`).checked) {
            console.log(`True`);
        } else {
            console.log(`False`);
        }
    }
});
document.addEventListener('DOMContentLoaded',()=>{
AddRow(0);
AddRow(1);
AddRow(2);
函数AddRow(i){
var table=document.getElementById('table');
var tbody=table.getElementsByTagName('tbody')[0];
var节点=document.createElement(“tr”);
node.setAttribute(“id”,i);
node.innerHTML=`;
tbody.appendChild(节点);
document.getElementById(`T${i}`).addEventListener('click',Toggle(i));
}
功能切换(一){
if(document.getElementById(`T${i}`)。选中){
log(`True`);
}否则{
console.log(`False`);
}
}
});

每次添加事件时都会调用函数切换。这就是Toggle(i)所做的。要定义要调用的函数而不实际调用它,只需使用不带括号的Toggle

addEventListener('click', Toggle)
但是,这会产生另一个问题,因为您希望将参数i传递给函数。要解决此问题,请为事件定义要执行的匿名函数,并在该匿名函数中调用Toggle函数并传递参数:

document.getElementById(`T${i}`).addEventListener('click', function() {
  Toggle(i);
});
document.addEventListener('DOMContentLoaded',()=>{
AddRow(0);
AddRow(1);
AddRow(2);
函数AddRow(i){
var table=document.getElementById('table');
var tbody=table.getElementsByTagName('tbody')[0];
var节点=document.createElement(“tr”);
node.setAttribute(“id”,i);
node.innerHTML=`;
tbody.appendChild(节点);
document.getElementById(`T${i}`).addEventListener('click',function(){
切换(i);
});
}
功能切换(一){
if(document.getElementById(`T${i}`)。选中){
log(`True`);
}否则{
console.log(`False`);
}
}
});

切换

我建议改为使用createElement()并将侦听器直接添加到创建的元素中,而不是将索引传递到click listener函数中

通过这种方式,您可以直接访问函数中的元素,而不必对其执行DOM查询

元素还内置了
insert
方法来简化行和单元格的创建

document.addEventListener('DOMContentLoaded',()=>{
const table=document.getElementById('table');
[0,1,2].forEach(AddRow);
console.log('tbody has',table.tBodies[0].rows.length,'rows')
函数AddRow(i){
const row=table.tBodies[0].insertRow();
row.id='row_'+i;
const checkbox=document.createElement('input');
checkbox.type=“checkbox”;
checkbox.id=`T${i}`;
复选框.addEventListener('单击',切换);
row.insertCell().append(复选框)
}
功能切换(事件){
log(`this.id}选中:${this.checked}`);
console.log('row id:',this.closest('tr').id)
}
});

切换