如何正确从动态表格中获取Input与Select控件的值?
问题修复:学生信息与课程成绩提交功能
原代码存在的问题
- 新增课程行时重复设置
id="lecture-name",DOM中id必须唯一,导致后续元素查找出错 - 中期、期末成绩输入框未设置标识(id/class),无法通过选择器定位
createStudent函数中元素选择器错误:- 用
row.querySelectorAll('lecture-name')获取课程选择框,属于无效选择器(缺少标签或属性标识) - 用
#midterm、#final查找输入框,但生成行时未给这些元素设置对应id
- 用
修复后的代码
1. 修改添加课程行的代码
const addLectureScoreBtn = document.getElementById("add-lecture-score-btn"); addLectureScoreBtn.addEventListener("click", () => { const lectureScoresTable = document.getElementById("lecture-score-table"); const newRow = document.createElement("tr"); // 课程选择列 const lectureNameCell = document.createElement("td"); const lectureNameSelect = document.createElement("select"); // 用class替代重复id,保留name属性 lectureNameSelect.className = "lecture-name-select"; lectureNameSelect.name = "lecture-name"; lectures.forEach((lecture) => { const option = document.createElement("option"); option.value = lecture.name; option.text = lecture.name; lectureNameSelect.add(option); }); lectureNameCell.appendChild(lectureNameSelect); newRow.appendChild(lectureNameCell); // 中期成绩列 const midtermCell = document.createElement("td"); const midtermInput = document.createElement("input"); midtermInput.type = "number"; midtermInput.value = 0; // 添加class用于定位 midtermInput.className = "midterm-score"; midtermInput.addEventListener("change", () => { if (midtermInput.value < 0 || midtermInput.value > 100) { midtermInput.value = 0; } }); midtermCell.appendChild(midtermInput); newRow.appendChild(midtermCell); // 期末成绩列 const finalCell = document.createElement("td"); const finalInput = document.createElement("input"); finalInput.type = "number"; finalInput.value = 0; // 添加class用于定位 finalInput.className = "final-score"; finalCell.appendChild(finalInput); newRow.appendChild(finalCell); // 删除按钮列 const actionsCell = document.createElement("td"); const deleteBtn = document.createElement("button"); deleteBtn.type = "button"; deleteBtn.textContent = "Delete"; deleteBtn.addEventListener("click", () => deleteRow(newRow)); actionsCell.appendChild(deleteBtn); newRow.appendChild(actionsCell); lectureScoresTable.appendChild(newRow); });
2. 修改createStudent函数
function createStudent() { const student = { id: 0, name: '', surname: '', lectures: [], gpa: 0 }; // 获取学生基础信息 const studentId = document.getElementById('student-id'); const studentName = document.getElementById('student-name'); const studentSurname = document.getElementById('student-surname'); // 获取表格并遍历数据行 const lectureScoresTable = document.getElementById("lecture-score-table"); lectureScoresTable.querySelectorAll('tr').forEach((row) => { // 定位行内元素,跳过无效行 const lectureSelect = row.querySelector('.lecture-name-select'); const midtermInput = row.querySelector('.midterm-score'); const finalInput = row.querySelector('.final-score'); if (!lectureSelect || !midtermInput || !finalInput) return; // 匹配对应的课程对象 const matchedLecture = lectures.find(lecture => lecture.name === lectureSelect.value); if (!matchedLecture) return; // 构造课程成绩对象 const lectureScore = { lecture: matchedLecture, midterm: Number(midtermInput.value), final: Number(finalInput.value) }; student.lectures.push(lectureScore); }); // 赋值学生基础信息 student.id = studentId.value; student.name = studentName.value; student.surname = studentSurname.value; // 计算GPA(确保calculateGPA函数能正确处理lectures数组) student.gpa = calculateGPA(student.lectures); // 将学生对象加入students数组 students.push(student); }
关键修改说明
- 元素标识优化:给动态生成的控件添加class替代重复id,避免DOM冲突,同时方便选择器定位
- 选择器修正:使用class选择器精准获取行内元素,解决原选择器无效的问题
- 数据校验:添加空值判断,避免因无效行或未匹配课程导致的报错
- 类型转换:将成绩输入框的字符串值转为数字,保证GPA计算的数据类型正确
内容的提问来源于stack exchange,提问作者Cedric Smith
相关产品推荐
相关产品推荐

