2013-03-22 91 views
13

首先,對不起我的英語不好......getElementsByClassName方法 - 奇怪的行爲

我寫了一個函數來改變類元素來改變其性質。 出於某種原因,只有一些元素髮生了變化,我花了幾個小時才找到解決方案,但他對我來說似乎很古怪,也許你可以向我解釋。

function replace(){ 
    var elements = document.getElementsByClassName('classOne'); 
    for (var i=0; i<elements.length;i++) { 
    elements[i].className = 'classTwo';    
    } 
} 

不工作爲好,Demo here,[對鉻25和FF],所以我把循環係數:

function replace(){ 
    var elements = document.getElementsByClassName('classOne'); 
    for (var i=0; i<elements.length;i) { //----here the different --- i without ++ 
    elements[i].className = 'classTwo';    
    } 
} 

這非常適用!似乎被稱爲「推」,並沒有係數需要... 這是正常的?這與我見過的例子不同。

在此先感謝!

回答

18

發生了什麼是一個奇怪的副作用。當您爲elements的每個元素重新分配className時,該元素將從數組中移除! (其實,正如@ user2428118指出的那樣,elements是一個類似於數組的對象,而不是數組,請參閱this thread)。這是因爲它不再具有classOne類名。當你的循環退出時(在第二種情況下),elements數組將爲空。通過增加i,你跳過有classOne類(原)元素的一半

while (elements.length) { 
    elements[0].className = 'classTwo'; // removes elements[0] from elements! 
} 

在你的第一種情況下,:

你可以寫你的環路。順便說一下,這是一個很好的問題。經過充分研究和明確。

+1

給予好評的答案和解釋 – 2013-03-22 04:08:40

+0

謝謝!聽起來沒錯.. 但是...它是有意義的編程? 「元素」是一個存在的對象,而不是動態的對象,沒有你可以改變? – MeNa 2013-03-22 04:38:12

+0

@MeNa - 儘管'elements'變量對你的函數是局部的,它所引用的數組也可以被DOM訪問(並由其維護)。每個元素的'className'屬性實際上觸發了DOM機制中的setter函數。該函數的一個副作用是從元素引用的數組中移除該元素。所以它不會改變「沒有你」;它會因爲您更改其某個元素的'className'屬性而發生更改。引用舊的聖賢:_「這不是一個錯誤,這是一個功能!」_ – 2013-03-22 04:47:04

4

getElementsByClassName返回一個NodeList。 NodeList集合是一個實時集合,這意味着文檔的修改會影響集合。 more

+0

Tnx。事實上,'現場收藏'這個詞很好地解釋了這一點。 – MeNa 2013-03-22 10:49:55

+1

並非所有NodeList集合都是實時的。某些「獲取」方法(如querySelectorAll())會返回不受後續DOM更改影響的STATIC NodeList。 – SHH 2014-12-27 05:25:21

-2

或恢復循環,通過長度爲1開始,下臺0

+0

你看過接受的答案嗎? – 2014-12-01 14:57:15

+0

是的,那也可以,但這個問題需要解釋而不是解決方案。下一次爲 – Bergi 2014-12-01 15:02:42

+0

,http:// stackoverflow。com/help /如何回答:)享受! – 2014-12-01 15:08:32