Javascript循环遍历节点数组获取备用条目

时间:2017-01-13 17:08:20

标签: javascript arrays for-loop

使用document.getElementsByClassName()创建数组后,我想更改每个元素的className属性。可以使用文字下标正确访问各个元素。但是,使用for循环时,例如:

for (i = 0; i < myElements.length; i += 1) { ... } 

我只获得备用元素,这似乎无视for循环正在做什么。在for执行后,已处理的元素不再在数组中,这也是无意的。

我已在http://www.mwpnz.com/classes/page.htm加载了测试页 (这包括广泛的调试代码,以查看正在发生的事情) 谢谢。

4 个答案:

答案 0 :(得分:2)

听起来您正在进行的更改是删除您搜索的类。

getElementsByClassName不返回数组,返回HTMLCollection。该集合是 live NodeList,这意味着它会自动跟踪DOM中的更改 - 如果添加/删除与该类匹配的元素,或者添加/删除类名,则集合更新本身。

这意味着如果在循环时从其中一个元素中删除该类,它将从集合中删除,并且所有以下元素的索引将向下移动。然后,当您递增索引时,您将跳过移动到刚刚操作的位置的元素。

简单的解决方案是首先将集合转换为数组。在ES6中,您可以使用Array.from()

var elementArray = Array.from(nodeList);

对于旧版浏览器,请使用

var elementArray = [].slice.call(nodeList);

请参阅Fastest way to convert JavaScript NodeList to Array?

答案 1 :(得分:1)

.getElementsByClassName返回 live nodeList,即如果您选择具有A className的元素,然后从其中一个元素中删除A className,则集合的.length属性已更改。

检查此示例:

enter image description here

您可以使用以下代码将nodeList转换为常规数组:

var nodeArr = Array.prototype.slice.call( myElements );

答案 2 :(得分:1)

保存myElements的副本,并遍历新数组。如:

myElements = document.getElementsByClassName("v1");
newArray = Array.from(myElements);

答案 3 :(得分:0)

在上述信息的帮助下,现在使用

正常工作
myElements = document.getElementsByClassName("v1");
while (myElements.length > 0) {
  // this will remove  myElements[0]  from the myElements nodelist
  myElements[0].className = myElements[0].className.replace("v1","vh1");
}