classList.remove是从HTMLCollection中删除元素的?

时间:2014-03-01 00:06:32

标签: javascript

我在使用JavaScripts新的classList API遇到一些非常奇怪的行为,比如我们有以下HTML代码:

<p class="testing">Lorem Ipsum</p>
<p class="testing">Lorem Ipsum</p>

以下JavaScript代码:

var elements = document.getElementsByClassName("testing");
alert(elements.length);
elements[0].classList.remove("testing");
alert(elements.length);

第一个警报将为您提供值2,而第二个警报将返回1.

似乎从元素中删除类也将其从elements HTMLCollection中删除,这对我来说毫无意义。

您可以看到此代码HERE的示例。

尝试使用以下代码从某些元素中删除某个类时遇到此问题:

var elements = document.getElementsByClassName('testing');
var elementsLength = elements.length - 1;
for(var i = 0; i <= elementsLength ; i++)
{
    elements[i].classList.remove('testing');
}

假设我们有两个元素,如上例所示,循环第一次成功运行,但第二次它在HTMLCollection中寻找不再存在的元素,所以我得到类似“TypeError:elements [i”的东西]未定义“。

您可以看到上述代码HERE

的示例

至少可以说这是令人沮丧的,我无法理解为什么/如何在调用classList.remove函数之前,classList.remove只会影响一次有效的数组集。我甚至无法在网上找到有关此行为的任何信息。

我在疯狂吗?或者我是否挖掘了一些没有人知道的classList api的奇怪隐藏功能?

2 个答案:

答案 0 :(得分:7)

document.getElementsByClassName返回的集合是实时的,所以如果一个元素不再具有该类,它将从集合中删除。

您可以创建该集合的非实时副本:

var elements = [].slice.call(document.getElementsByClassName('testing'));

或者考虑到它的存在:

while (elements.length) elements[0].classList.remove('element-focus');

答案 1 :(得分:1)

使用document.getElementsByClassName返回实时HTMLCollection

HTML DOM中的HTMLCollection处于活动状态;更改基础文档后,它会自动更新。

因此(如plalx's answer中所述),如果您删除元素的类,则该元素将从基于该类的HTMLCollection中删除。

相反,您可以使用document.querySelectorAll返回静态NodeList集合:

Document方法querySelectorAll()返回一个静态(非实时)NodeList,表示与指定选择器组匹配的文档元素列表。

因此您的代码将从更改

var elements = document.getElementsByClassName("testing");

以类名"testing"作为参数,

var elements = document.querySelectorAll(".testing");

以类选择器".testing"作为参数。

然后您可以遍历elements,这将是一个静态NodeList。