Tomasz Kapłoński
Tomasz Kapłoński

Reputation: 1378

JS DOM append child does not work

I am trying to implement a simple function that gets some list of elements (in this case I pass some <li> elements) and append them in random order to some parent node (<ul>). To do this I wrote something like that:

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);
    }
}

As you can see I do check if the randomly chosed index actually still exists in the tmpList and if it's actually html element. However though when I run this code I get:

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

What do I do wrong?

ps. Please don't give me advices like "use jquery" or "just concatenate it using innerHTML" because there are reasons I cannot use them.

[edit] parent element is defined a few lines earlier so it's not the case.

UPDATE

I made some changes according to one answer so the code looks as follow:

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;

Now it looks a little bit better but still works strange. Now the console output is:

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

So it has li elements but does not treat them as HTMLNode... :o (the same result was when I used elem !== null && elem !== undefined && elem.nodeType === 1)

Upvotes: 0

Views: 408

Answers (3)

Epsil0neR
Epsil0neR

Reputation: 1704

You declared maxIndex before while and in while you change your array, so I advice you to change:

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

to (this will ensure that curIndex will be always less than tmpList.lenght)

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

then splice your array and validate your element: (for better validation you should check if your elem is html element)

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]);
        }
    }
}  

Upvotes: 1

Tomasz Kapłoński
Tomasz Kapłoński

Reputation: 1378

Ok, I found the problem. Trick is that elem holds list containing one matching element. THe solution is to use elem[0].

Upvotes: 0

Justinas
Justinas

Reputation: 43479

You don't have element named parent

Upvotes: 0

Related Questions