【问题标题】:How to create a JavaScript loop that adds DOM properties to attributes?如何创建一个将 DOM 属性添加到属性的 JavaScript 循环?
【发布时间】:2020-11-22 18:44:19
【问题描述】:

我有一个表格,其中的单元格不是contentEditable。但是,使用 JavaScript 循环或函数,我想这样做。

我知道为每个单元格手动执行此操作非常简单,对于只有几个单元格的表格来说这可能会更容易,但我想通过表格的循环/函数来加快这个过程变得更大,手动将每个单元格设置为 contentEditable 所花费的时间会很乏味。

下面是一个显示表格计算器的快速示例,目前无法编辑。但是使用循环或函数,我想将右列中的每个单元格设置为 DOM 中的.contentEditable = true。我想参数看起来像(var i = 0; l != rows.length; i < l; i+2),但我正在努力解决参数后面的语句必须是什么才能使循环/函数工作。任何帮助将不胜感激!

function myFunction() {
  var jack2 = document.getElementById("jack").innerText;
  var john2 = document.getElementById("john").innerText;
  var joe2 = document.getElementById("joe").innerText;

  var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);

  document.getElementById("total").innerHTML = total2;
}
table {
  width: 100%;
}

table,
tr,
th,
td {
  border: 1px solid gray;
  border-collapse: collapse;
  font-family: Arial;
  margin: 5px;
}
<table>
  <caption>Weight Calculator</caption>
  <tr class="cell">
    <th>Person</th>
    <th>Weight (kg)</th>
  </tr>
  <tr class="cell">
    <td>Jack</td>
    <td id="jack" oninput="myFunction()">1</td>
  </tr>
  <tr class="cell">
    <td>John</td>
    <td id="john" oninput="myFunction()">2</td>
  </tr>
  <tr class="cell">
    <td>Joe</td>
    <td id="joe" oninput="myFunction()">3</td>
  </tr>
  <tr class="cell">
    <td>Total</td>
    <td id="total"></td>
  </tr>
</table>

【问题讨论】:

    标签: javascript arrays function for-loop


    【解决方案1】:

    获取表格中所有具有左邻居的单元格(标题不受影响,因为有 th 而不是 td)。将您的属性添加到这些单元格中的每一个。

    已编辑:为了获取总数,请在每个 td 上添加一个事件监听器,如果内容发生变化,该事件监听器会调用 calc 函数。

    function myFunction() {
        let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
        weightCells.forEach(td => {
            td.setAttribute('contentEditable', true);
            td.addEventListener ("change", calcSum());
        });
    }
    
    function calcSum() {
        let sum=0;
        let weightCells = document.querySelectorAll("table tr td ~ td");
        let count = weightCells.length-1;
        for (i=0; i<count; i++) {
            sum +=  parseInt(weightCells[i].innerHTML) || 0;
        }
      weightCells[count].innerHTML = sum;
    }
    
    myFunction();
    table {
      width: 100%;
    }
    
    table,
    tr,
    th,
    td {
      border: 1px solid gray;
      border-collapse: collapse;
      font-family: Arial;
      margin: 5px;
    }
    <table>
      <caption>Weight Calculator</caption>
      <tr class="cell">
        <th>Person</th>
        <th>Weight (kg)</th>
      </tr>
      <tr class="cell">
        <td>Jack</td>
        <td id="jack" oninput="myFunction()">1</td>
      </tr>
      <tr class="cell">
        <td>John</td>
        <td id="john" oninput="myFunction()">2</td>
      </tr>
      <tr class="cell">
        <td>Joe</td>
        <td id="joe" oninput="myFunction()">3</td>
      </tr>
      <tr class="cell">
        <td>Total</td>
        <td id="total"></td>
      </tr>
    </table>

    【讨论】:

      【解决方案2】:

      您可以选择整个表,然后使用 querySelectorAll 获取所有行,然后为每一行更改第二个 td 的 contenteditable,如下所示

      codepen

      let table = document.getElementById('table')
      let rows = table.querySelectorAll('tr')
      
      rows.forEach(row => {
        let tds = row.querySelectorAll('td') 
        // all the cells of the row
        if (tds.length > 0) { // if it is not the header
          tds[1].contentEditable = true 
          // change the contenteditable
        }
      })
      
      

      (如果您有多个表,则需要在表中添加 id)

      <table id="table">
      ...
      </table>
      
      

      【讨论】:

      • 这很棒,但它也使最终的单元格可编辑。有没有办法解决这个问题?
      • 是的,你可以看看我的回答来解决这个问题。选择器可以扩展一点。
      猜你喜欢
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      相关资源
      最近更新 更多