Javascript classList.remove无法正常工作

检查这个小提琴: JSFiddle

HTML:

Some text 1/15 Some text 2/16
Some text 3/17 Some text 4/18
Some text 5/19 Some text 6/20
Some text 7/21 Some text 8/22
Some text 9/23 Some text 10/24
Some text 11/25 Some text 12/26
Some text 13/27 Some text 14/28

JavaScript的:

 var myTbl = document.getElementsByClassName("myTable")[0]; var tSomeStyleClasses = myTbl.getElementsByClassName("someStyle"); console.log(tSomeStyleClasses); for (i=0;i<tSomeStyleClasses.length;i++) { console.log(tSomeStyleClasses[i].classList); //tSomeStyleClasses[i].classList.remove("someStyle"); } var tOtherStyleClasses = myTbl.getElementsByClassName("otherStyle"); console.log(tOtherStyleClasses); for (i=0;i<tOtherStyleClasses.length;i++) { console.log(tOtherStyleClasses[i].classList); //tOtherStyleClasses[i].classList.remove("otherStyle"); } 

并检查控制台日志。 每个都有10个条目,someStyle和otherStyle。 现在取消注释//tSomeStyleClasses[i].classList.remove("someStyle");//tOtherStyleClasses[i].classList.remove("otherStyle"); 然后跑小提琴。 再次检查控制台日志。 应删除2 x 10个样式,但它只删除5个样式。 我想知道为什么?

.getElementsByClassName()返回的值是实时 NodeList。 它是“实时”意味着当您更改列表中的元素时,列表本身会自动更新。 因此,当您删除用于查找元素的类时,列表会变短。 因为您使用数字索引进行迭代,所以最终会跳过元素。

处理它的一个好方法是使用一个简单的while循环,只在列表的第一个元素上操作,直到列表为空:

 var tSomeStyleClasses = myTbl.getElementsByClassName("someStyle"); while (tSomeStyleClasses.length) { tSomeStyleClasses[0].classList.remove("someStyle"); } 

因为getElementsByClassName为您提供了匹配元素的实时列表。 从索引0处的元素中删除该类时,将立即更新列表以从列表中删除该元素并将所有其他元素向下移动。 因为然后递增i现在索引0处的元素不会被处理。

或者:

  1. 向后通过列表,或者

  2. 使用document.querySelectorAll(".someStyle") ,它返回快照列表,而不是实时快照列表