如何实现填完行内双输入框后自动新增有效表格行?
可动态新增双输入框行的表格实现方案
问题场景与需求
- 制作每行包含
first name和last name输入框的表格 - 当前问题:仅第一行可正常工作,新增行无需填写内容即可继续新增,且系统仅检测第一行输入
- 核心需求:实现可动态新增带双输入框的表格,每个输入框需唯一,最终要收集所有输入生成姓名列表
问题根源
- 重复绑定事件:每次调用
addRow都为table绑定一次change事件,导致事件叠加,且事件仅关联当前创建的行输入框,逻辑混乱 - 输入框无唯一标识:未给输入框设置唯一标识,后续无法精准对应每行的姓和名
- 自动新增逻辑错误:未判断触发输入的是哪一行,仅第一行有值就触发新增,不符合需求
修正后的完整代码
HTML 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="author" content="Christian Davis"> <link rel="stylesheet" href="styles.css"> <title>Random Group Generator</title> </head> <body> <article id="input-article"> <table id="table" border="1"> <tr> <th>First Name:</th> <th>Last Name:</th> </tr> </table> <br> <button id="addRow">Add Row</button> <button id="submit">Submit</button> <div id="nameList"></div> <!-- 用于展示收集到的姓名列表 --> </article> <script src="app.js"></script> </body> </html>
CSS 代码
#input-article.hidden { display: none; } table { text-align: center; align-items: center; } th { width: 50vmin; height: 10vmin; font-size: 20pt; font-weight: 800; } input { width: 50vmin; height: 5vmin; text-align: center; font-size: 18pt; font-weight: 400; font-family: Georgia, 'Times New Roman', Times, serif; border: 0; padding: 0; } #submit { background-color: blue; color: white; border: 0; position: absolute; left: 95vmin; } #output-article.hidden { display: none; } #nameList { margin-top: 20px; font-size: 16pt; }
JavaScript 代码
const table = document.querySelector('#table'); const addRowButton = document.querySelector('#addRow'); const submitButton = document.querySelector('#submit'); const nameList = document.querySelector('#nameList'); let rowCounter = 0; // 用于生成唯一的输入框标识 let names = []; // 存储所有收集到的姓名 // 创建行的核心函数 function addRow() { const row = table.insertRow(-1); const cell1 = row.insertCell(0); const cell2 = row.insertCell(1); const firstNameInput = document.createElement("input"); const lastNameInput = document.createElement("input"); // 设置唯一name属性,方便后续收集数据 firstNameInput.name = `firstName-${rowCounter}`; lastNameInput.name = `lastName-${rowCounter}`; firstNameInput.type = "text"; cell1.appendChild(firstNameInput); lastNameInput.type = "text"; cell2.appendChild(lastNameInput); rowCounter++; } // 仅绑定一次change事件,使用事件委托处理所有行的输入变化 table.addEventListener('change', (e) => { // 只处理输入框的变化 if (e.target.tagName !== 'INPUT') return; // 获取当前输入框所属的行号 const rowIndex = e.target.name.split('-')[1]; const firstNameInput = document.querySelector(`input[name="firstName-${rowIndex}"]`); const lastNameInput = document.querySelector(`input[name="lastName-${rowIndex}"]`); // 检查当前行的两个输入是否都有值,且当前是最后一行时才新增 const lastRowIndex = rowCounter - 1; if (rowIndex == lastRowIndex && firstNameInput.value.trim() && lastNameInput.value.trim()) { addRow(); } }); // 收集所有姓名的函数 function collectNames() { names = []; for (let i = 0; i < rowCounter; i++) { const firstName = document.querySelector(`input[name="firstName-${i}"]`)?.value.trim(); const lastName = document.querySelector(`input[name="lastName-${i}"]`)?.value.trim(); if (firstName && lastName) { names.push({ firstName, lastName }); } } // 展示收集到的列表 nameList.innerHTML = '<h3>姓名列表:</h3>' + names.map((item, index) => `<p>${index+1}. ${item.firstName} ${item.lastName}</p>`).join(''); } // 绑定按钮事件 addRowButton.addEventListener('click', addRow); submitButton.addEventListener('click', collectNames); // 页面加载时自动创建第一行 addRow();
关键实现说明
- 输入框唯一标识:通过
rowCounter给每个输入框生成唯一的name属性,确保后续能精准匹配每行的姓和名 - 事件委托优化:仅给表格绑定一次
change事件,避免重复绑定导致的逻辑混乱,同时能处理所有新增行的输入变化 - 精准新增逻辑:仅当最后一行的两个输入框都有内容时,才自动新增一行,避免无意义的空行
- 数据收集功能:
collectNames函数遍历所有输入框,收集有效姓名并展示,满足生成列表的需求
内容的提问来源于stack exchange,提问作者That New Coder
相关产品推荐
相关产品推荐

