如何使用JavaScript循环遍历计算按顺序命名的表单元素
问题解决方法
你之前写的循环代码跑不通,本质是搞错了模板字符串的作用:模板字符串拼出来的只是普通文本字符串,既不能直接当变量引用,也不能放在等号左边当赋值目标,完全没必要用eval去拼代码执行——JS本身就支持方括号语法动态访问对象属性,刚好适配这个场景。
直接替换updt函数为下面的代码就能正常运行:
const updt = () => { const f = document.forms['myform']; // 实际业务有20行就把循环的终止条件改成 n <= 20 即可 for (let n = 1; n <= 3; n++) { // 做数值转换和空值兜底,避免空输入、非数字输入算出NaN const col1Val = Number(f[`r${n}c1`].value) || 0; const col2Val = Number(f[`r${n}c2`].value) || 0; f[`r${n}c3`].value = col1Val * col2Val; } }
写法说明
- 表单元素集合原生支持通过
[属性名字符串]访问对应name的输入框,动态拼接出的name字符串放在方括号里,和你之前硬编码写f.r1c1的访问效果完全一致 - 取值时用
Number()把输入框的字符串值转成数值,搭配|| 0做兜底,就算输入框为空、填入了非数字内容,结果框也不会显示无意义的NaN - 后续如果行数调整,只需要改循环的终止值就行,不用逐行重复写赋值逻辑,不管是3行还是20行,代码量都不会增加
- 不要用
eval实现这类需求,eval会直接执行传入的任意字符串代码,存在代码注入的安全风险,执行性能也比原生属性访问差很多
如果后续表单行是动态增减的,不想每次手动修改循环上限,也可以用更灵活的自动遍历写法,不需要提前知道总行数:
const updt = () => { const f = document.forms['myform']; // 自动匹配所有c1列的输入框,提取对应行号计算 f.querySelectorAll('input[name^="r"][name$="c1"]').forEach(c1Input => { const rowId = c1Input.name.slice(1, -2); const c2Input = f[`r${rowId}c2`]; const resInput = f[`r${rowId}c3`]; if (!c2Input || !resInput) return; const val1 = Number(c1Input.value) || 0; const val2 = Number(c2Input.value) || 0; resInput.value = val1 * val2; }) }
内容的提问来源于stack exchange,提问作者Richard Akindele
相关产品推荐
相关产品推荐

