我在使用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的奇怪隐藏功能?
答案 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。