javascript - 制作一个 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;
解决方案
使用简单的 for循环的简短答案是:
- 循环遍历每一行
- 对于每一行,将数量乘以价格
- 同一行的输出总计
由于我们基本上总是希望每一行都有一个“总计”字段,我们可以直接在 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
属性只阻止表单提交,我们必须自己编写值钳制代码。这很容易通过读取属性的值并将值限制在其定义的范围内来完成。请注意,我们为min
and添加了默认值max
,它们是最低和最高的安全整数值。
推荐阅读
- sql-server - SQL Server 计数相同结果聚合函数
- python - 试图从网站获取数据但没有来
- azure-active-directory - 如何使用 ms graph api 仅列出 AAD 中的特定组?
- javascript - 比较两个 JSON 对象并验证数据不匹配
- javascript - 带日期的 SQL 查询在节点 mssql 中返回日期时间
- php - 在 jenkins 容器中安装 php 和 composer
- ofx - 如何在 Power BI 中解析 a-ofx-version-1-0-2-file?
- c++ - 在 C++ 中初始化一个数组
- python - 我的删除功能中的逻辑有问题吗?
- uml - Enterprise Architect:如何将多条概括线组合成一条线