首页 > 解决方案 > 制作一个 for 循环来计算特定单元格,然后将结果写入行中的最后一个单元格

问题描述

我对 JS 很陌生,我正在尝试学习 for 循环,在这种情况下,如果可能的话,我想把它变成一个 for 循环。我想计算单元格 3 中的静态数字字符串,乘以单元格 4 中的输入数字,并将结果输出到已在循环中创建的新单元格 5。任何帮助深表感谢

var table = document.getElementById("table");

var Row1 = table.rows[1],
    cell1 = Row1.insertCell(5);
var Row2 = table.rows[2],
    cell2 = Row2.insertCell(5);
var Row3 = table.rows[3],
    cell3 = Row3.insertCell(5);
var Row4 = table.rows[4],
    cell4 = Row4.insertCell(5);
var Row5 = table.rows[5],
    cell5 = Row5.insertCell(5);
var Row6 = table.rows[6],
    cell6 = Row6.insertCell(5);

var x1 = table.rows[1].cells[4].getElementsByTagName('input')[0].value;
var y1 = table.rows[1].cells[3].innerHTML;
    cell1.innerHTML = y1 * x1;
var x2 = table.rows[2].cells[4].getElementsByTagName('input')[0].value;
var y2 = table.rows[2].cells[3].innerHTML;
    cell2.innerHTML = y2 * x2;
var x3 = table.rows[3].cells[4].getElementsByTagName('input')[0].value;
var y3 = table.rows[3].cells[3].innerHTML;
    cell3.innerHTML = y3 * x3;
var x4 = table.rows[4].cells[4].getElementsByTagName('input')[0].value;
var y4 = table.rows[4].cells[3].innerHTML;
    cell4.innerHTML = y4 * x4;
var x5 = table.rows[5].cells[4].getElementsByTagName('input')[0].value;
var y5 = table.rows[5].cells[3].innerHTML;
    cell5.innerHTML = y5 * x5;
var x6 = table.rows[6].cells[4].getElementsByTagName('input')[0].value;
var y6 = table.rows[6].cells[3].innerHTML;
    cell6.innerHTML = y6 * x6;

标签: javascripthtml

解决方案


使用简单的 for循环的简短答案是:

  1. 循环遍历每一行
  2. 对于每一行,将数量乘以价格
  3. 同一行的输出总计

由于我们基本上总是希望每一行都有一个“总计”字段,我们可以直接在 HTML 中添加它。
由于我们知道价格元素和数量元素的位置,我们可以使用固定值作为索引来访问它们。

var rows = document.querySelectorAll("#pricetable tbody tr");
for (var i = 0; i < rows.length; ++i) {
  var price = rows[i].children[3].innerHTML;
  var quantity = rows[i].children[4].children[0].value;
  var total = price * quantity; // Implicit type-casting to numbers
  rows[i].children[5].innerHTML = total;
}
<table id="pricetable">
  <thead>
    <tr>
      <th>Number</th>
      <th>Product</th>
      <th>Brand</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>23456789</td>
      <td>Phone</td>
      <td>Apple</td>
      <td>6500</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
    <tr>
      <td>22256289</td>
      <td>Phone</td>
      <td>Samsung</td>
      <td>6200</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
    <tr>
      <td>24444343</td>
      <td>Phone</td>
      <td>Huawei</td>
      <td>4200</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
    <tr>
      <td>19856639</td>
      <td>Tablet</td>
      <td>Apple</td>
      <td>4000</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
    <tr>
      <td>39856639</td>
      <td>Tablet</td>
      <td>Samsung</td>
      <td>2800</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
    <tr>
      <td>12349862</td>
      <td>Tablet</td>
      <td>Huawei</td>
      <td>3500</td>
      <td>
        <input type="text" size="3" value="1" />
      </td>
      <td></td>
    </tr>
  </tbody>
</table>

注意:当改变这些元素的位置时(例如通过在它们前面添加一个新列),它们的索引会发生变化。这将使您必须手动更新 JS 文件中的索引。
您可以通过使用这个简单的“技巧”让自己更轻松:
将特定的类添加到元素(例如.price.quantity.total),让您可以使用Element.querySelector().

注意:脚本只运行一次,第一次加载页面。这意味着,输入不同的数量不会更新“总计”字段。为此,我们需要一个EventListener

另一种方法
通过观察for循环,我们可以看到:

  • 每次迭代我们只访问一行
  • 我们访问每一行的顺序无关紧要

由于这两个点都被检查,我们可以使用for...of循环(也称为foreach循环或增强的 for循环)。for...of循环(在我看来)更易于阅读,并告诉我们使用上面的列表本身检查的内容。
注意:请注意for...of-loop 和 for...in-loop 的区别

现在,我们可以在循环中立即计算总数,但提前考虑,我们希望在输入新的数量值时再次执行相同的计算。我们可以通过将计算变成一个Function 来减少重复代码updateRowTotal(),使代码更易于调试理解。

要在输入新数量值时实际更新总计,我们可以使用EventListener,它会在将新值输入到 - 字段时自动调用函数<input>(通过调用updateRowTotal(evt.target.closest("tr")))。

function clamp(min, value, max) {
  return Math.max(min, Math.min(value, max));
}

for (let row of document.querySelectorAll("#pricetable tbody tr")) {
  updateRowTotal(row);
  row.querySelector("input.quantity").addEventListener("input", evt => {
    // Add '/*' before this comment to "remove" this extra part
    // The 5 lines below are to clamp 'value' between 'min' and 'max'
    let min = parseInt(evt.target.getAttribute("min"));
    let max = parseInt(evt.target.getAttribute("max"));
    if (isNaN(min)) min = Number.MIN_SAFE_INTEGER;
    if (isNaN(max)) max = Number.MAX_SAFE_INTEGER;
    evt.target.value = clamp(min, evt.target.value, max);
    // */
    updateRowTotal(evt.target.closest("tr"));
  });
}

function updateRowTotal(row) {
  row.querySelector(".total").innerHTML = row.querySelector(".price").innerHTML * row.querySelector(".quantity").value;
}
<table id="pricetable">
  <thead>
    <tr>
      <th>Price</th>
      <th>Quantity</th>
      <th>Row-Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="price">6500</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
    <tr>
      <td class="price">6200</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
    <tr>
      <td class="price">4200</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
    <tr>
      <td class="price">4000</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
    <tr>
      <td class="price">2800</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
    <tr>
      <td class="price">3500</td>
      <td>
        <input class="quantity" type="number" min="0" max="999" value="1" />
      </td>
      <td class="total"></td>
    </tr>
  </tbody>
</table>

旁注
制作-<input>字段type="number"可防止输入任何非数字字符。
而且由于min- 和 -max属性只阻止表单提交,我们必须自己编写值钳制代码。这很容易通过读取属性的值并将值限制在其定义的范围内来完成。请注意,我们为minand添加了默认值max,它们是最低和最高的安全整数值


推荐阅读