Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can change child elements order in JS?

I have this html:

<table>
    <tr>
        <td>
            Set right order
        </td>
        <td>
            <span style = "display: block;">asd | <a href = '#' onclick = "moveChoiceTo(this, -1);">&uarr;</a><a href = '#' onclick = "moveChoiceTo(this, 1);">&darr;</a></span>
            <span style = "display: block;">dsa | <a href = '#' onclick = "moveChoiceTo(this, -1);">&uarr;</a><a href = '#' onclick = "moveChoiceTo(this, 1);">&darr;</a></span>
            <span style = "display: block;">qwe | <a href = '#' onclick = "moveChoiceTo(this, -1);">&uarr;</a><a href = '#' onclick = "moveChoiceTo(this, 1);">&darr;</a></span>
            <span style = "display: block;">ewq | <a href = '#' onclick = "moveChoiceTo(this, -1);">&uarr;</a><a href = '#' onclick = "moveChoiceTo(this, 1);">&darr;</a></span>
        </td>
    </tr>
</table>

And this JS:

function moveChoiceTo(elem_choice, direction)
{
    var curr_index = -1; //index of elem that we should move
    var td = elem_choice.parentElement.parentElement; //link to TD

    for (var i = 0; i < td.children.length; i++) //determine index of elem that called this function
        if (td.children[i].children[0] == elem_choice)
        {
            curr_index = i;
            break;
        }

    if (curr_index == -1)
        return;

    if (curr_index == 0 && direction < 0) //if nowhere to move
        return;

    if (curr_index == td.children.length - 1 && direction > 0) //if nowhere to move
        return;

    var curr_child = td.children[curr_index]; //save current elem into temp var
    td.children.splice(curr_index, 1); //here I getting exception that splice isn't supported by object, but arent this is array?
    td.children.splice(curr_index + direction, 0, curr_child); //attempt to insert it
}

I getting exception that splice isn't supported, but this supposed to be an array and support this method? What other ways I have to change children order?

like image 886
Kosmo零 Avatar asked Sep 15 '14 14:09

Kosmo零


2 Answers

I will add the answer with simpler (and better) approach:

function moveChoiceTo(elem_choice, direction) {

    var span = elem_choice.parentNode,
        td = span.parentNode;

    if (direction === -1 && span.previousElementSibling) {
        td.insertBefore(span, span.previousElementSibling);
    } else if (direction === 1 && span.nextElementSibling) {
        td.insertBefore(span, span.nextElementSibling.nextElementSibling)
    }
}

The key idea is using insertBefore method properly. You also don't need to remove anything from DOM.

Demo: http://jsfiddle.net/dq8a0ttt/

like image 154
dfsq Avatar answered Sep 20 '22 17:09

dfsq


Splice is not supproted in HTMLCollection, you need to use .removeChild and .insertBefore something like this:

var before = td.children[curr_index + direction];
var child = td.children[curr_index];

td.removeChild(child);
td.insertBefore(child, before); //attempt to insert it      
like image 29
Aleksandar Gajic Avatar answered Sep 19 '22 17:09

Aleksandar Gajic