JavaScript等待元素渲染后绑定JS对象及动态元素事件失效问题
问题原因
innerHTML +=操作会先清空容器内所有现有DOM节点,再将拼接后的完整HTML字符串重新解析为DOM渲染。原有节点上绑定的所有事件监听器会随旧节点销毁全部丢失,只有最后一次添加的元素绑定的事件可以正常触发。
解决方法
方法1:修改元素添加逻辑,避免重绘原有节点
不要用innerHTML +=拼接内容,改用appendChild添加新节点,原有节点不会被销毁,事件绑定自然保留。
仅需修改ContainerObj的add方法即可:
add(item) { // 先创建临时容器生成新DOM节点 const tempDiv = document.createElement('div') tempDiv.innerHTML = itemHTML(item.name, item.price) const newItem = tempDiv.firstElementChild // 追加到容器,不会影响原有节点 this.self.appendChild(newItem) this.items.push( new ItemObj(newItem) ) }
方法2:使用事件委托优化逻辑(更推荐)
直接把删除事件绑定在父容器#container上,不用每个子元素单独绑定,既避免事件丢失问题,也减少内存占用:
- 删掉
ItemObj构造函数里的删除按钮事件绑定代码 - 在
ContainerObj构造函数里添加事件监听:
constructor (self){ this.self = self this.items = [] // 事件委托处理删除 this.self.addEventListener('click', (e) => { if(e.target.classList.contains('item__delete-button')) { e.target.closest('.item').remove() // 可在这里补充逻辑同步删除this.items里的对应对象 } }) }
其他优化建议
- 代码里传递参数时写的
self = xxx属于多余写法,直接传对应值即可,不影响功能但属于不规范写法。 - 现有
name和price的setter只是给属性赋值,没有同步更新DOM内容,后续如果要修改这两个属性的话需要补充DOM更新逻辑。
内容的提问来源于stack exchange,提问作者Lama'
相关产品推荐
相关产品推荐

