如何用JavaScript实现单按钮批量多组输入乘法运算及结果导出PDF
功能实现方案
需求梳理
现有代码仅支持计算单组两个输入值的乘积,需实现单次点击按钮完成以下功能:
- 阶段1:对N组两两输入的数值分别执行乘法运算
- 阶段2:将每组得到的乘积结果先乘以模组系数(半模组为1、全模组为2),再乘以预设硬编码固定值20得到最终结果
- 阶段3:将所有最终运算结果导出为PDF格式
现有代码问题
原HTML中重复使用了相同的id属性(firstNumber、secondNumber、opt、result),HTML规范要求id必须全局唯一,因此原JS只能获取到第一组输入的值,无法处理多组数据。
修改后的完整代码
HTML代码
<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>装修面积成本计算器</title> <link rel="stylesheet" href="style.css"> <!-- 引入PDF导出库 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> </head> <body> <script src="calculation.js"></script> <form> <br> <p class="test">主卧 :</p> <p>衣柜顶柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <!-- 衣柜 --> <p>衣柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <br> <p class="test">儿童房 :</p> <p>衣柜顶柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <!-- 衣柜 --> <p>衣柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <p class="test">客房 :</p> <p>衣柜顶柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <!-- 衣柜 --> <p>衣柜 :</p> <div class="calc-group"> <label><b>宽度 :</b></label> <input type="number" class="width-input" /> <label><b>高度 :</b></label> <input type="number" class="height-input" /> <label> <span class="result-span"></span></label> </br> <div class="col-lg-1"> <select class="opt-select form-control"> <option>半模组</option> <option>全模组</option> </select> </div> </div> <input type="button" class="registerbtn" onClick="calcAndExport()" value="计算并导出PDF" /> </form> </body> </html>
JS代码(calculation.js)
// 预设硬编码固定值 const FIXED_MULTIPLIER = 20; // 所有组的分类名称,和HTML顺序对应 const GROUP_NAMES = [ "主卧-衣柜顶柜", "主卧-衣柜", "儿童房-衣柜顶柜", "儿童房-衣柜", "客房-衣柜顶柜", "客房-衣柜" ]; async function calcAndExport() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const calcGroups = document.querySelectorAll(".calc-group"); const allResults = []; // 遍历所有组计算结果 calcGroups.forEach((group, index) => { const width = parseFloat(group.querySelector(".width-input").value) || 0; const height = parseFloat(group.querySelector(".height-input").value) || 0; const opt = group.querySelector(".opt-select").value; // 模组系数 const modCoefficient = opt === "全模组" ? 2 : 1; // 计算最终结果 const baseProduct = width * height; const finalResult = baseProduct * modCoefficient * FIXED_MULTIPLIER; // 显示结果到页面 group.querySelector(".result-span").innerText = `结果:${finalResult}`; // 收集结果用于导出 allResults.push({ name: GROUP_NAMES[index], width, height, type: opt, result: finalResult }); }); // 生成PDF doc.setFontSize(16); doc.text("装修计算结果汇总", 20, 20); doc.setFontSize(12); let yPosition = 30; allResults.forEach((item, index) => { if (yPosition > 280) { doc.addPage(); yPosition = 20; } const line = `${index+1}. ${item.name} | 宽度:${item.width} 高度:${item.height} | 类型:${item.type} | 最终结果:${item.result}`; doc.text(line, 20, yPosition); yPosition += 10; }); // 下载PDF doc.save("装修计算结果.pdf"); }
CSS代码(仅修正了原代码的属性错误,其余逻辑不变)
body { font-family: Arial, Helvetica, sans-serif; background-color: #fff; } * { box-sizing: border-box; } /* Add padding to containers */ .container { padding: 16px; background-color: white; } /* Full-width input fields */ input[type=text], input[type=password] { width: 20%; padding: 15px; margin: 5px 0 22px 0; display: inline-block; border: none; background: #f1f1f1; } input[type=text]:focus, input[type=password]:focus { background-color: #ddd; outline: none; } input[type=number], input[type=password] { width: 20%; padding: 15px; margin: 5px 0 22px 0; display: inline-block; border: none; background: #f1f1f1; } input[type=number]:focus, input[type=password]:focus { background-color: #ddd; outline: none; } /* Overwrite default styles of hr */ hr { border: 1px solid #f1f1f1; margin-bottom: 25px; } /* Set a style for the submit button */ .registerbtn { background-color: #626463; color: white; padding: 16px 20px; margin: 8px 0; border: none; cursor: pointer; width: 20%; opacity: 0.9; } .registerbtn:hover { opacity: 1; } /* Add a blue text color to links */ a { color: dodgerblue; } /* Set a grey background color and center the text of the "sign in" section */ .signin { background-color: #f1f1f1; text-align: center; } p.test{ margin: 15px 0 5px !important; font-size: 18px; text-transform: uppercase; background-color: aliceblue; width: 20%; }
内容的提问来源于stack exchange,提问作者murthy
相关产品推荐
相关产品推荐

