给动态创建的Checkbox添加EventListener无效问题排查
问题解决:动态创建的复选框点击无响应
问题描述
点击添加任务按钮后,成功生成包含复选框的任务项,但点击该复选框时无任何响应,控制台也未输出报错信息。
原因分析
问题出在这行代码:
taskDiv.innerHTML += `<i class="fa-regular fa-trash-can trashCan"></i>`
使用innerHTML +=时,浏览器会先把taskDiv内现有DOM结构序列化为字符串,拼接新内容后再重新解析生成新的DOM节点。这会导致之前通过createElement创建并添加到taskDiv中的checkBox元素被重新创建,原来绑定了事件的checkBox对象和页面上实际存在的复选框节点失去关联,事件监听自然失效。
解决方案
方案一:用DOM方法创建并添加元素(推荐)
避免使用innerHTML修改DOM,改用createElement创建垃圾桶图标,再通过appendChild添加到taskDiv中:
// 替换原有的 taskDiv.innerHTML += ... 代码 const trashIcon = document.createElement('i'); trashIcon.className = 'fa-regular fa-trash-can trashCan'; taskDiv.appendChild(trashIcon);
方案二:延迟绑定事件(效率较低,不推荐)
如果坚持使用innerHTML,需要在DOM更新完成后重新获取复选框元素再绑定事件:
// 将事件绑定代码移到 tasksAreaDiv.appendChild(taskWrapperDiv) 之后 tasksAreaDiv.appendChild(taskWrapperDiv); // 重新获取页面上的复选框 const newCheckBox = taskDiv.querySelector('.taskCheckBox'); newCheckBox.addEventListener('click', function() { console.log('any text'); });
修正后的完整JS代码
let addTaskBtn = document.querySelector('.inputPlusSign') let tasksAreaDiv = document.querySelector('.tasksArea') let inputText = document.querySelector('#taskInput') addTaskBtn.addEventListener('click', function() { let taskWrapperDiv = document.createElement('div') taskWrapperDiv.setAttribute('class', 'taskWrapper') let taskDiv = document.createElement('div') taskDiv.setAttribute('class', 'task') let label = document.createElement('label') label.setAttribute('class', 'checkContainer') let checkBox = document.createElement('input') checkBox.setAttribute('type', 'checkbox') checkBox.setAttribute('class', 'taskCheckBox') let checkBoxSpan = document.createElement('span') checkBoxSpan.setAttribute('class', 'checkmark') let taskTextSpan = document.createElement('span') taskTextSpan.setAttribute('class', 'taskText') taskTextSpan.innerText = inputText.value label.appendChild(checkBox) label.appendChild(checkBoxSpan) taskDiv.appendChild(label) taskDiv.appendChild(taskTextSpan) // 改用DOM方法创建垃圾桶图标 const trashIcon = document.createElement('i'); trashIcon.className = 'fa-regular fa-trash-can trashCan'; taskDiv.appendChild(trashIcon); taskWrapperDiv.appendChild(taskDiv) tasksAreaDiv.appendChild(taskWrapperDiv) checkBox.addEventListener('click', function() { console.log('any text') }) })
内容的提问来源于stack exchange,提问作者Lasha Lashashvili
相关产品推荐
相关产品推荐

