2013-04-13 140 views
1

我想将类hidden中的所有元素更改为类appeared。这里是我的代码:更改某些元素的类名称

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

即有名为隐藏类三个要素中的两个,改变。这是为什么?如何解决它?我尝试使用getElementById,它的工作原理,但我需要使它通用,所以我可以使用它许多元素和许多类。

编辑

原来有类似问题的线程。我的代码更改为这一点,它的工作原理:

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

不要忘记'var'或者问题会出现。 – elclanrs

+4

你应该提供一个[完整的例子](http://sscce.org)你的问题,因为你现在的代码看起来很好(除了缺少'var's)。你可以使用http://jsfiddle.net或类似的网站。 – Zeta

+2

通过做'e [i] .className =“出现”;'你也删除所有其他类。我希望你意识到这一点?考虑改为修改'classList'。 –

回答

0

你为什么不使用jQuery和使用show()和隐藏()方法:

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

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

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

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

要包括的jQuery在结尾处添加这个脚本你的身体标记:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
+0

这是一个学校项目,不允许图书馆,是的,这就像重新发明轮子,但这样,学生将探索更多关于该语言,我的技术援助。 – shankshera

1

的问题是,getElementsByClassName返回NodeList,这是一个live collection。因此,每次您询问其长度时,系列都会重新计算。由于您已经更改了某些元素的className,因此循环会比您预期的更早结束。

如果您检查ilength每个循环的值,你将有:

  • 第一次,长度为3(0 < 3)是,所以它改变了它的类。
  • 第二次,长度为2.(1 < 2)为true,所以它改变了它的类。 (2 < 1)是false。它不会改变它的类。

你应该节点列表转换为数组:

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

或者你可以使用你提供的替代码,虽然在这种情况下,选择重新计算每次你问其length属性的时间。

0

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

下面是一个例子情形:

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

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

  • 通过首先将其内容复制到另一个数组来使其成为静态。这是jQuery采用的大多数库的方法。
  • 利用活跃。正如您在编辑中展示的那样,您可以使用现场收藏来获得优势。通过始终在当前视图中的第一个元素上操作,您将永远不会跳过任何元素。循环条件也是微不足道的:你只需要继续迭代直到视图不再包含任何元素。