原生JS:为何keydown事件中我的函数无法运行?
问题解决:按下Enter键触发表格新增行
原代码核心问题
- 每次调用
addRow()都会给window重复绑定keydown事件,导致按一次Enter触发多次回调 - 直接调用
onRowChange()时未传递事件对象e,函数内e.target会报错,逻辑无法执行 - 全局监听未判断触发场景,任何地方按Enter都会触发新增行逻辑
修改方案
- 将
keydown事件移到全局,仅绑定一次,避免重复绑定 - 在事件回调中判断触发元素是否为表格内的输入框,且按下的是Enter键
- 调整
onRowChange逻辑,直接通过触发的输入框定位当前行,确保输入验证正常执行
修正后的完整代码
JavaScript
const table = document.querySelector('#table'); const addRowButton = document.querySelector('#addRow'); let firstNamesArray = []; let lastNamesArray = []; let rowNumber = 0; function addRow() { let row = table.insertRow(-1); let cell1 = row.insertCell(0); let cell2 = row.insertCell(1); let firstNameInput = document.createElement("input"); let lastNameInput = document.createElement("input"); firstNameInput.type = "text"; firstNameInput.setAttribute('id', `firstName${rowNumber}`); cell1.appendChild(firstNameInput); lastNameInput.type = "text"; lastNameInput.setAttribute('id', `lastName${rowNumber}`); cell2.appendChild(lastNameInput); } function onRowChange(targetInput) { // 获取当前输入框所在的行 const currentRow = targetInput.parentNode.parentNode; // 检查当前行两个输入框是否都有值 const inputs = currentRow.querySelectorAll('input'); const allFilled = [...inputs].every(input => input.value.trim() !== ''); if (allFilled) { createNames(rowNumber); rowNumber++; addRow(); } } function createNames(index) { let firstName = document.getElementById(`firstName${index}`).value; let lastName = document.getElementById(`lastName${index}`).value; firstNamesArray.push(firstName); lastNamesArray.push(lastName); } // 全局仅绑定一次keydown事件 window.addEventListener('keydown', (event) => { if (event.key === 'Enter') { // 阻止Enter默认行为(如表单提交) event.preventDefault(); // 判断触发元素是否为表格内的输入框 if (event.target.tagName === 'INPUT' && event.target.closest('#table')) { onRowChange(event.target); } } }, false); addRowButton.addEventListener('click', () => { addRow(); addRowButton.disabled = true; });
CSS
table { text-align: center; align-items: center; border: 1px solid black; border-collapse: collapse; } th { width: 50vmin; height: 10vmin; font-size: 20pt; font-weight: 800; } input { width: 50vmin; height: 5vmin; text-align: center; align-items: center; font-size: 18pt; font-weight: 400; font-family: Georgia, 'Times New Roman', Times, serif; border: 0; padding: 0; }
HTML
<html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="styles.css"> </head> <body> <article id="input-article"> <table id="table" border="1"> <tr> <th>First Name:</th> <th>Last Name:</th> </tr> </table> <br> <div id="buttons"> <button id="addRow">Add Row</button> <button id="submit">Submit</button> </div> </article> <script src="app.js"></script> </body> </html>
关键修改说明
- 事件绑定优化:全局仅绑定一次
keydown事件,避免重复绑定导致的多次触发 - 场景判断:仅在表格内的输入框按下Enter时才执行新增逻辑,避免全局误触发
- 逻辑简化:通过触发的输入框直接定位当前行,输入验证逻辑更可靠
- 默认行为阻止:添加
event.preventDefault()避免Enter键触发表单默认提交
内容的提问来源于stack exchange,提问作者That New Coder
相关产品推荐
相关产品推荐

