动态设置td类名并添加div时,div内容混入类名的问题
动态修改TD类名时Div内容混入类名的问题分析
问题描述
执行以下操作时出现DOM结构异常:
- 为td元素动态设置类名
- 向该td元素动态追加div元素
错误生成的DOM结构
<td class="GSCBRI<div><p>Telefon : </p></div> 17"> <div> <p>Telefon : </p> </div> </td>
预期正确的DOM结构
<td class="GSCBRI 17"> <div> <p>Telefon : </p> </div> </td>
问题代码
row.childNodes.forEach((el) => { el.setAttribute('class', `${row.childNodes[0].innerHTML} ${i}`); i++; let htmlDiv = document.createElement('div'); let htmlp = document.createElement('p'); htmlp.innerText = 'Telefon : '; htmlDiv.appendChild(htmlp); htmlDiv.setAttribute('style', 'display:none;') el.appendChild(htmlDiv); })
注释掉el.appendChild(htmlDiv)后,类名恢复正常但无法添加div,疑问:为什么div内容会混入td的类名中?
原因分析
问题出在row.childNodes[0].innerHTML这一行:
当循环处理第一个td时,你给它插入了div元素,此时row.childNodes[0]的innerHTML已经从原来的纯文本GSCBRI,变成了包含新插入div的完整HTML内容。后续循环处理其他td时,再去读取row.childNodes[0].innerHTML,就会把这个带div的HTML字符串直接拼接到类名里,导致类名结构异常。
解决方案
提前把初始的类名前缀保存下来,避免循环过程中节点内容被修改影响后续操作:
// 提前获取并保存初始的类名前缀,用textContent避免HTML内容干扰 const classNamePrefix = row.childNodes[0].textContent.trim(); row.childNodes.forEach((el) => { el.setAttribute('class', `${classNamePrefix} ${i}`); i++; let htmlDiv = document.createElement('div'); let htmlp = document.createElement('p'); htmlp.innerText = 'Telefon : '; htmlDiv.appendChild(htmlp); htmlDiv.setAttribute('style', 'display:none;') el.appendChild(htmlDiv); })
如果row.childNodes[0]的初始内容是纯文本,也可以直接用textContent替代innerHTML,不过提前保存前缀是更稳妥的方案,能彻底避免后续节点内容变化带来的影响。
内容的提问来源于stack exchange,提问作者BoogaBooga
相关产品推荐
相关产品推荐

