2014-04-11 67 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