复用已删除ID的UI元素无法二次隐藏的问题求助
问题:复用已删除ID的列表项无法再次移除
我开发了一个支持添加、移除列表项的功能,列表最多可包含10个项。点击「Add Unit」按钮添加UI元素,「Remove Unit」按钮通过display: none隐藏元素。但添加带有曾被删除过的ID的元素时,无法再次隐藏或删除该元素。
问题原因
问题核心在于移除操作仅通过display: none隐藏元素并清空innerHTML,但该元素仍保留在DOM树中,其ID并未被释放。当后续复用相同ID创建新元素时,document.getElementById会优先找到之前被隐藏的旧元素,导致新元素的移除按钮无法正确指向自身。
解决方案
将移除逻辑改为直接从DOM树中删除元素,彻底释放ID,避免新旧元素ID冲突。
修改后的完整代码
HTML部分
<!DOCTYPE html> <html> <head> <style> div.container { width: 100%; border: 1px solid gray; background-color: silver; } .button { background-color: silver; padding: 6px 8px 6px 16px; margin-top: 10px; color: '#000'; font-size: 1.2vw; margin-left: 20px; border: none; outline: none; font-family: sans-serif; } .main { margin-left: 13%; font-size: 1.5vw; padding: 0px 10px; margin-Top: 13%; padding-bottom: 50px; height: 100%; } .submitButton { height: 50px; width: 40%; margin-top: 20px; font-size: 20px; border-radius: 10px; font-family: sans-serif } .addItemButton { height: 40px; width: 20%; margin-top: 20px; font-size: 20px; border-radius: 10px; align-items: flex-end; justify-self: flex-end; font-family: sans-serif } .removeItemButtonView { height: 40px; width: 20%; font-size: 20px; border-radius: 10px; align-items: flex-end; justify-self: flex-end; font-family: sans-serif } .submitButton:hover { background-color: #007893; color: #fff } input { height: 34px; width: 60%; text-align: center; font-size: 20px; border: 1px solid #ddd; border-radius: 4px; display: inline-block; vertical-align: middle; margin: 10px 0px; } .inputWidth { width: 40%; } .detailBox, .sceneBox { display: flex; flex-direction: row; align-items: flex-end; justify-content: space-between; border-bottom: 1px solid gray; padding: 20px; } </style> </head> <body style="background-color: silver;"> <div class="container"> <div class="sticky"> <header> </header> </div> <div class="main"> <div class="cmdevice"> </div> <button type="button" class="addItemButton" onclick="addItem()">Add Unit</button> </div> </div> </body> </html>
JavaScript部分
let deviceArr = [] const cmdevice = document.querySelector('.cmdevice'); function addItem() { if (deviceArr.length >= 10) { return; } deviceArr.sort((a, b) => a - b); let newId = 1; for (let i = 0; i < deviceArr.length; i++) { if (deviceArr[i] === newId) { newId++; } else { break; } } deviceArr.push(newId); console.log('newId', newId) let cmItem = document.createElement('div'); cmItem.setAttribute("id", `cm${newId}`); cmItem.innerHTML = `<div style="border: 1px solid; border-radius: 25px; margin: 30px 0px" > <div class="seperator" style="margin: 30px 0px; padding: 0px 20px; display: flex; justify-content: space-between; align-items: center"> <label>Device ${newId}</label> <button type="button" class="removeItemButtonView" onclick="onClickRemoveCMItem(${newId})" >Remove Unit</button> </div> <div class="detailBox"> <div>Line Number</div> <br> <input class="input inputWidth" type="text" name="line${newId}" id="line${newId}" value="" /> </div> <div class="detailBox" style="border-bottom: 0px" > <div>Area No</div> <br> <input class="input inputWidth" type="text" name="area${newId}" id="area${newId}" value="" /> </div>`; cmdevice.append(cmItem); } function onClickRemoveCMItem(id) { let ind = deviceArr.indexOf(id) console.log(deviceArr, id, ind) if (ind !== -1) { deviceArr.splice(ind, 1) console.log('del', id) const item = document.getElementById(`cm${id}`) if (item) { // 直接从DOM中删除元素,而非仅隐藏 item.remove(); } } }
关键修改点
- 将
onClickRemoveCMItem函数中的a.style.display = 'none'和a.innerHTML = ''替换为item.remove(),彻底删除DOM元素,释放对应的ID - 移除了未使用的
counter变量,精简代码
内容的提问来源于stack exchange,提问作者react Raylogic
相关产品推荐
相关产品推荐

