动态创建HTML节点CSS不生效 树形视图节点修改后无法折叠展开
问题原因
页面初始化阶段仅对当时存在的所有.caret类节点绑定了点击折叠/展开事件,你使用outerHTML替换原有节点时,旧节点连同绑定在它身上的事件会被一起销毁,新插入的.caret节点没有绑定对应的点击事件,所以点击后没有响应,并不是CSS没有生效。
另外你的替换逻辑存在DOM结构错误:你要替换的是<span id="test">这个节点,它的外层已经有<li>标签了,但你写的替换内容里又嵌套了一层<li>,会导致DOM层级混乱,后续的节点查找逻辑也会出错。
额外提示:你提供的CSS代码中,
span.caret-down::before样式里-webkit-transform行末尾多了一个多余的单引号,会导致样式解析错误,建议删掉。
解决方案
优先推荐使用事件委托实现,该方案不需要在每次新增/替换节点后重复绑定事件,适配所有动态生成的节点:
- 删掉原有初始化时绑定点击事件的代码,替换为以下代码:
// 将事件绑定到树的根节点,所有子节点的点击事件都会冒泡到此处处理 document.getElementById('myUL').addEventListener('click', function(e) { // 仅处理点击.caret节点的场景 if (e.target.classList.contains('caret')) { e.target.parentElement.querySelector(".nested").classList.toggle("active"); e.target.classList.toggle("caret-down"); } })
- 修正
myFunction里的替换内容,去掉多余的<li>标签:
function myFunction() { document.getElementById("test").outerHTML = `<span id="test2" class="caret">BEAR</span> <ul class="nested"> <li>Black Tea</li> <li>White Tea</li> <li>Green Tea</li> </ul>` }
如果不想用事件委托,也可以在每次替换节点后手动给新的.caret节点绑定事件,不过这种方案维护成本更高,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Mervius
相关产品推荐
相关产品推荐

