CSS nth-child选择器在JS动态生成表格中失效问题排查
动态生成表格后,
:nth-child(even)选择器仅选中第一个元素的问题分析与解决 其实问题的根源不是appendChild没有更新兄弟节点,而是你用错了DOM选择方法!
为什么只选中第一个元素?
你在configureTable里用了document.querySelector("#list tbody tr:nth-child(even)")——这个方法的特性就是返回匹配选择器的第一个元素,不管页面里有多少符合条件的元素。哪怕你写的是2n或者even,它只会挑第一个符合的行出来,所以自然只有第一行偶数行被设置了背景色。
正确的解决办法
要选中所有偶数行,你需要用document.querySelectorAll(),它会返回所有匹配的元素集合,然后遍历这个集合来设置样式:
function configureTable() { // 拿到所有偶数行 var tbEvenRows = document.querySelectorAll("#list tbody tr:nth-child(even)"); // 遍历每一行设置背景色 tbEvenRows.forEach(row => { row.style.backgroundColor = "cyan"; }); }
额外的小bug提醒
我注意到你生成表格行的代码里有个容易忽略的问题:在r.map(function(d) { ... })的循环里,你每次遍历一个单元格就把<tr>追加到tbody里了。这会导致同一行被重复添加多次(比如一行有3个单元格,就会被append 3次),虽然你说表格显示正确,但大概率是笔误,应该把tbBody.appendChild(tr)放到r.map的外面,等所有单元格都加到行里之后,再把整行加到tbody:
// 添加行的修正代码 var tbBody = document.querySelector('#list tbody'); data.map(function(r) { var tr = document.createElement('tr'); r.map(function(d) { var td = document.createElement('td'); td.textContent = d; tr.appendChild(td); }); // 把整行加到tbody,放在r.map外面! tbBody.appendChild(tr); });
更优雅的方案:直接用CSS
其实完全不需要用JS来设置交替行颜色,直接写CSS规则就可以,动态生成的元素也会自动应用这些样式,不用手动调用配置函数:
#list tbody tr:nth-child(even) { background-color: cyan; }
这样不管你什么时候动态添加行,样式都会自动生效,比JS操作更简洁高效。
内容的提问来源于stack exchange,提问作者Adriano_Pinaffo
相关产品推荐
相关产品推荐

