2014-04-11 107 views
0

我想實現一個簡單的函數,獲取一些元素列表(在這種情況下,我通過一些<li>元素)並將它們以隨機順序追加到某個父節點(<ul>)。要做到這一點,我寫了這樣的事情:JS DOM追加孩子不工作

console.log(tmpList); 
var maxIndex = tmpList.length; 
while(tmpList.length > 0) { 
    var curIndex = Math.floor(Math.random() * maxIndex); 
    if(tmpList[curIndex] && tmpList[curIndex].nodeType===1) { 
     var elem = tmpList.splice(curIndex, 1); 
     console.log(elem); 
     parent.appendChild(elem); 
    } 
} 

正如你可以看到我做檢查,如果隨機chosed指數居然還在tmpList存在,如果它實際上是html元素。但是,當我運行此代碼時,我得到:

[li, li, li, li] 
[li] 
NotFoundError: Failed to execute 'appendChild' on 'Node': The new child element is null. 

我該怎麼做?

ps。請不要給我這樣的建議,如「使用jQuery」或「只是使用innerHTML連接」,因爲我有些理由不能使用它們。

parent元素定義了幾行,所以情況並非如此。

while(tmpList.length > 0) { 
    var curIndex = Math.floor(Math.random() * tmpList.length); 
    var elem = tmpList.splice(curIndex, 1); 
    console.log(elem); 
    if(elem instanceof HTMLElement) { 
     //console.log(curIndex); 

     console.log(elem); 
     parent.appendChild(elem); 
    } 
} 
return true; 

現在看起來更好一點,但仍然有效奇怪:

UPDATE

我根據一個答案,使代碼看起來如下做了一些改動。現在控制檯輸出爲:

[li, li, li, li] 
[li] 
[li] 
[li] 
[li] 

所以它擁有li元素,但不把他們當作HTMLNode ...:O(相同的結果,當我用elem !== null && elem !== undefined && elem.nodeType === 1

+0

你如何在if循環中加入'if(typeof elem!== null)parent.appendChild(elem);'到你的循環中? – techouse

+0

您可以提供一個JSFiddle,它引發您在控制檯中看到的相同錯誤嗎?那麼幫助會容易得多。 –

+0

http://jsfiddle.net/UR3ZQ/ <但是我沒有看到任何控制檯有錯誤 – Moby04

回答

1

while之前聲明maxIndexwhile你改變你的陣列,所以我建議你改:

var curIndex = Math.floor(Math.random() * maxIndex); 

到(這將確保curIndex將永遠小於tmpList.lenght)

var curIndex = Math.floor(Math.random() * tmpList.length); 

然後拼接你的陣列和驗證元素:(爲了更好的驗證,你應該檢查你的elem是HTML元素)

while(tmpList.length > 0) { 
    var curIndex = Math.floor(Math.random() * tmpList.length); 
    if (curIndex < tmpList.lenght){ 
     var elem = tmpList.splice(curIndex, 1); 
     // array.splice returns array of removed from array elements, so you need work with first element in that array. 

     if (elem[0] instanceof HTMLElement && elem[0].nodeType === 1){ 
      //Add to parent: 
      parent.appendChild(elem[0]); 
     } 
    } 
} 
+0

我想過,但如果我刪除tmpList [1],那麼tmpList.length將有值3(在這種情況下)和數學.random()* tmpList.length永遠不會生成值3,所以它永遠不會刪除tmpList [3] ...無所謂,我檢查了它。 – Moby04

+0

可以說'arr'有3個項目,所以'arr.lenght'是3,但是'arr [3]'將返回undefined或null,因爲數組是從零開始的,這意味着'arr [0]'是第一個項目,'arr [1]'是第二項,'arr [2]'是第三項。 Math.random()第一個圓圈的最大值爲2(第三個項目的索引) – Epsil0neR

+0

我知道這一點。雖然JS在中間刪除某些元素時不改變索引(我的意思是如果我有索引0,1,2並刪除它可以有0,2用null代替1) – Moby04

0

你不必元素命名parent

+0

實際上,父母是一個元素作爲一個函數參數前面傳遞。我只是粘貼了一部分。此外,請注意,瀏覽器不報告該父項爲空(它有appendChild方法) – Moby04

0

好的,我發現了這個問題。竅門是elem擁有​​包含一個匹配元素的列表。該解決方案是使用elem[0]

+1

在控制檯中很容易忽略[]。無法告訴你我曾經被這種類型的東西咬過多少次,以及我告訴自己多少次它永遠不會再發生。 –

+0

是的,最瑣碎的錯誤是最糟糕的錯誤...... :) http://www.smashingapps.com/2010/12/18/what-its-like-to-be-a-programmer.html – Moby04