JavaScript表格单元格编辑:Save按钮功能失效求助
问题:表格编辑功能中Save按钮失效
点击Edit按钮后,单元格能切换为可编辑状态,Edit/Delete按钮也能替换成Save按钮,但Save按钮点击后完全无响应,需要修复该功能。
用户提供的原代码
原JavaScript代码
function deleteButtons(btns, tdBtns) { for (let index = 0; index < btns.length; index += index) { tdBtns.removeChild(btns[index]); } } function createButtons(bool, td) { if (bool) { var Edit = document.createElement('input'); Edit.type = "button"; Edit.value = "Edit"; Edit.setAttribute('onclick', 'Edit(this)'); td.appendChild(Edit); var Delete = document.createElement('input'); Delete.type = "button"; Delete.setAttribute('onclick', 'Delete(this)'); Delete.value = "Delete"; td.appendChild(Delete); } else { var Save = document.createElement('input'); Save.type = "button"; Save.value = "Save"; Save.setAttribute('onclick', 'Save(this)'); td.appendChild(Save); } } function Add() { var p1 = document.getElementById("txt").value; const row1 = document.getElementById("row1"); var table = document.getElementById("MyTable"); //insert row beginning or end var element = document.createElement("tr"); var table = document.getElementById("MyTable"); table.appendChild(element); if (document.getElementById('input1').checked) { table.insertBefore(element, table.firstElementChild); } else if (document.getElementById('input2').checked) { table.lastElementChild.after(element); } var case1 = document.createElement("td"); case1.innerHTML = p1; element.appendChild(case1); var case2 = document.createElement("td"); element.appendChild(case2); createButtons(true, case2); } //delete: function Delete(element) { element.parentNode.parentNode.parentNode.removeChild(element.parentNode.parentNode); } //Edit: function Edit(element) { const row = element.parentNode.parentNode; const tdList = row.children; for (let index = 0; index < tdList.length - 1; index++) { const element = tdList[index]; var str = element.childNodes[0].nodeValue; var input = document.createElement("input"); input.type = "text"; input.id = "edit" + (index + 1).toString(); input.value = str; element.removeChild(element.childNodes[0]); element.appendChild(input); } const tdBtns = tdList[1]; const btns = tdBtns.children; deleteButtons(btns, tdBtns); createButtons(false, tdBtns); } function Save(element) { const row = element.parentNode.parentNode; const tdList = row.children; /* const edit = [ ['edit1'], ['edit2'] ]; */ const edit = []; for (let index = 0; index <= 1; index++) { edit[index] = document.getElementById("edit" + (index + 1).toString()).value; if (edit[index] == "") { alert("You must not keep textboxes empty"); var empty = true; } } if (!empty) { for (let index = 0; index < tdList.length - 1; index++) { tdList[index].removeChild(tdList[index].children[0]); var text = document.createTextNode(edit[index]); tdList[index].appendChild(text); } const tdBtns = tdList[1]; const btns = tdBtns.children; deleteButtons(btns, tdBtns); createButtons(true, tdBtns); } }
原HTML代码
<h1>Table</h1> <div id="principal"> <div id="cntr"><input type="text" id="txt" placeholder="Element to add."> <input type="button" value="Add" onclick="Add()"><br><br></div> <form id="frm"> Add : <input type="radio" name="test" id="input1"> at the beginning <input type="radio" name="test" id="input2"> at the end </form><br> <table id="MyTable"> <tbody> <tr id="row1"> <td id="name_row1">Element 1 </td> <td> <input type="button" id="edit_button1" value="Edit" onclick="Edit(this)"> <input type="button" value="Supprimer" onclick="Delete(this)"> </td> </tr> </table> </div>
问题根源及修复方案
1. deleteButtons函数循环逻辑错误
原循环写的index += index,第一次循环index为0,之后永远是0,既不会遍历按钮,还会导致浏览器卡死。另外btns是动态HTML集合,删除元素时长度会变化,需转成数组遍历。
2. Save函数中empty变量未初始化
empty仅在输入为空时声明赋值,初始状态为undefined,!empty会被判定为true,逻辑混乱。需提前初始化empty = false。
3. 编辑框ID重复问题
原代码给编辑框设置固定ID(edit1、edit2),同时编辑多行时ID会重复,导致document.getElementById无法获取当前行的输入框。改为直接从当前行DOM节点获取输入框,无需ID。
4. 其他细节优化
- 使用
closest('tr')代替多层parentNode,代码更简洁鲁棒 - 给默认选中的单选按钮添加
checked属性,避免Add功能初始无默认值 - 用
textContent代替innerHTML,避免XSS风险
修复后的完整代码
修复后的JavaScript代码
function deleteButtons(btns, tdBtns) { // 转成数组遍历,避免动态集合的长度变化问题 Array.from(btns).forEach(btn => { tdBtns.removeChild(btn); }); } function createButtons(bool, td) { if (bool) { const EditBtn = document.createElement('input'); EditBtn.type = "button"; EditBtn.value = "Edit"; EditBtn.onclick = () => Edit(EditBtn); td.appendChild(EditBtn); const DeleteBtn = document.createElement('input'); DeleteBtn.type = "button"; DeleteBtn.onclick = () => Delete(DeleteBtn); DeleteBtn.value = "Delete"; td.appendChild(DeleteBtn); } else { const SaveBtn = document.createElement('input'); SaveBtn.type = "button"; SaveBtn.value = "Save"; SaveBtn.onclick = () => Save(SaveBtn); td.appendChild(SaveBtn); } } function Add() { const p1 = document.getElementById("txt").value.trim(); if (!p1) { alert("请输入要添加的内容"); return; } const table = document.getElementById("MyTable"); const row = document.createElement("tr"); // 根据单选框位置插入行 if (document.getElementById('input1').checked) { table.insertBefore(row, table.firstElementChild); } else { table.appendChild(row); } const contentTd = document.createElement("td"); contentTd.textContent = p1; row.appendChild(contentTd); const btnTd = document.createElement("td"); row.appendChild(btnTd); createButtons(true, btnTd); // 清空输入框 document.getElementById("txt").value = ""; } function Delete(element) { element.closest('tr').remove(); } function Edit(element) { const row = element.closest('tr'); const contentTds = row.querySelectorAll('td:not(:last-child)'); contentTds.forEach(td => { const text = td.textContent.trim(); const input = document.createElement("input"); input.type = "text"; input.value = text; td.textContent = ''; td.appendChild(input); }); const btnTd = row.querySelector('td:last-child'); deleteButtons(btnTd.children, btnTd); createButtons(false, btnTd); } function Save(element) { const row = element.closest('tr'); const contentTds = row.querySelectorAll('td:not(:last-child)'); let empty = false; const values = []; contentTds.forEach(td => { const input = td.querySelector('input'); const val = input.value.trim(); if (!val) { alert("输入框不能留空"); empty = true; } values.push(val); }); if (!empty) { contentTds.forEach((td, index) => { td.textContent = values[index]; }); const btnTd = row.querySelector('td:last-child'); deleteButtons(btnTd.children, btnTd); createButtons(true, btnTd); } }
修复后的HTML代码
<h1>Table</h1> <div id="principal"> <div id="cntr"> <input type="text" id="txt" placeholder="Element to add."> <input type="button" value="Add" onclick="Add()"><br><br> </div> <form id="frm"> Add : <input type="radio" name="test" id="input1"> at the beginning <input type="radio" name="test" id="input2" checked> at the end </form><br> <table id="MyTable" border="1"> <tbody> <tr id="row1"> <td id="name_row1">Element 1 </td> <td> <input type="button" id="edit_button1" value="Edit" onclick="Edit(this)"> <input type="button" value="Delete" onclick="Delete(this)"> </td> </tr> </tbody> </table> </div>
内容的提问来源于stack exchange,提问作者nigeria
相关产品推荐
相关产品推荐

