1

我想将所有带有 class 的元素更改hidden为 class appeared。这是我的代码:

e = document.getElementsByClassName("hidden");
for (i = 0; i < e.length; i++) {
    e[i].className = "appeared";
}

类名为 hidden 的三个元素中的两个发生了变化。这是为什么?如何解决?我尝试使用getElementById,它有效,但我需要使其通用,以便我可以将它用于许多元素和许多类。

编辑

原来有一个类似问题的线程。我将代码更改为此并且它可以工作:

e = document.getElementsByClassName("hidden");
while (e.length) {
    e[0].className = "appeared";
}
4

3 回答 3

1

The problem is that getElementsByClassName returns a NodeList, which is a live collection. Thus, every time you asked for its length, the collection is recalculated. Since you have already changed the className for some elements, the loop ends earlier than you expected.

If you check the values for i and length for each loop, you will have:

  • The first time, length is 3. (0 < 3) is true, so it changes its class.
  • The second time, length is 2. (1 < 2) is true, so it changes its class.
  • The first time, length is 1. (2 < 1) is false. It doesn't change its class.

You should convert the NodeList to an array:

var e = [].slice.call(document.getElementsByClassName("hidden"));

Or you can use the alternative code you provided, although in that case the selection is recalculated every time you ask for its length property.

于 2013-04-13T09:43:30.073 回答
0

为什么不使用 jQuery 并使用 show() 和 hide() 方法:

显示类名“隐藏”的所有元素:

$('.hidden').show();

隐藏类名“隐藏”的所有元素:

$('.hidden').hide();

要包含 jQuery,请在 body 标记的末尾添加此脚本:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
于 2013-04-13T09:31:16.227 回答
0

您的原始代码失败的原因是因为getElementsByClassName返回了带有 class 的元素的实时视图hidden。因此,当您在循环中更改元素的类时,此更改会反映在视图中,并且该元素将不再存在。

这是一个示例场景:

  1. e最初包含 3 个hidden元素。
  2. 在第一次迭代中,i == 0ande[0]被更改为不再 hidden。这意味着e现在只包含 2 个元素,因为删除hidden了“旧” 。e[0]
  3. 在第二次迭代中,iis 已经在1e[0]仍然一个hidden元素。这意味着您将跳过e[0]e[1]在循环之前)。在本次迭代中,您将删除e[1]e[2]之前的)类,视图减少到 1 个元素。
  4. 由于i(= 2) 现在超过e.length(= 1),循环终止。

最终结果是您跳过了旧的e[1]. 有两种方法可以解决这个问题:

  • 通过首先将其内容复制到另一个数组来制作e静态。这是大多数库(例如 jQuery)采用的方法。
  • 利用活泼。正如您在编辑中所展示的那样,您可以利用实时集合来发挥自己的优势。通过始终对视图中的当前第一个元素进行操作,您将永远不会跳过任何元素。循环条件也很简单:您只需要不断迭代,直到视图不再包含任何元素。
于 2013-04-13T09:47:43.223 回答