2013-04-13 169 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採用的大多數庫的方法。
  • 利用活躍。正如您在編輯中展示的那樣,您可以使用現場收藏來獲得優勢。通過始終在當前視圖中的第一個元素上操作,您將永遠不會跳過任何元素。循環條件也是微不足道的:你只需要繼續迭代直到視圖不再包含任何元素。