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

时间:2021-04-20 02:11:58

标签: javascript html events onclick

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

问题是,我添加到复选框的点击事件仅在页面加载时触发 - 页面刷新时控制台会生成 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`);
        }
    }
});

2 个答案:

答案 0 :(得分:0)

每次添加事件时都会调用函数 Toggle。这就是 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);

  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', function() {
      Toggle(i);
    });
  }

  function Toggle(i) {
    if (document.getElementById(`T${i}`).checked) {
      console.log(`True`);
    } else {
      console.log(`False`);
    }
  }
});
<table id="table">
  <thead>
    <tr>
      <th scope="col">Toggled</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

答案 1 :(得分:0)

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

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

<table> 元素还内置了 insert 方法以简化行和单元格的创建

document.addEventListener('DOMContentLoaded', () => {
  const table = document.getElementById('table');
  [0,1,2].forEach(AddRow);
  console.log('tbody has ', table.tBodies[0].rows.length, ' rows') 

  function AddRow(i) {    
    const row = table.tBodies[0].insertRow();
    row.id = 'row_' + i;    
    const checkbox = document.createElement('input');
    checkbox.type = "checkbox";
    checkbox.id = `T${i}`;
    checkbox.addEventListener('click', Toggle);
    row.insertCell().append(checkbox)
  }

  function Toggle(event) {
    console.log(`${this.id} checked: ${this.checked}`);
    console.log('row id: ', this.closest('tr').id)
  }
});
<table id="table">
  <thead>
    <tr>
      <th scope="col">Toggled</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

相关问题