views:

1575

answers:

6

Let's say I have three <div> elements on a page. How can I swap positions of the first and third <div>? jQuery is fine.

+8  A: 

Trivial with jQuery

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

If you want to do it repeatedly, you'll need to use different selectors since the divs will retain their ids as they are moved around.

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});
tvanfosson
There's a bug somewhere. It only appears to work twice. http://jsbin.com/evedu
Ionuț G. Stan
I was only expecting it to work once.
tvanfosson
@Ionut -- the point being that it depends on the relative positioning of the elements. Once you change the order you can no longer find the first and third by their ids and need to work out another way. My answer was only meant to illustrate the functionality of the methods to accomplish the requested task, not be a comprehensive solution to swapping the first and third divs in a set an arbitrary number of times.
tvanfosson
Yes, you're right. It's because it relied on IDs.
Ionuț G. Stan
A: 

If you have jQuery on the page, this post should answer your question.

Atømix
No it doesn't, it's all about visibility with CSS, nothing to do with DOM rearrangement.
ijw
There was no mention of changing the DOM. Just to swap elements around visibly.
Atømix
+1  A: 
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

and use it like this:

$('#div1').swap('#div2');

if you don't want to use jQuery you could easily adapt the function.

Darin Dimitrov
+7  A: 

There's no need to use a library for such a trivial task:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, third

This takes account of the fact that getElementsByTagName returns a live NodeList that is automatically updated to reflect the order of the elements in the DOM as they are manipulated.

You could also use:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, third

and there are various other possible permutations, if you feel like experimenting:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

for example :-)

NickFitz
True, but it's hard to argue with the elegance and readability that something like jQuery provides - not to mention the enhanced capabilities out of the box.
Crazy Joe Malloy
That said, +1 for the bare-coded approach.
Crazy Joe Malloy
Yes, but who only does this one thing?
tvanfosson
... or only has 3 divs on the page
rpflo
@everybody: the original question asked how to swap the third and first divs on a page that had three divs. That was the question I answered. If the OP had a more complex question, they should have asked it, and they would have got a more complex answer ;-)
NickFitz
A: 

Jquery approach mentioned on the top will work. You can also use JQuery and CSS .Say for e.g on Div one you have applied class1 and div2 you have applied class class2 (say for e.g each class of css provides specific position on the browser), now you can interchange the classes use jquery or javascript (that will change the position)

Rajat
+1  A: 
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

This function may seem strange, but it heavily relies on standards in order to function properly. In fact, it may seem to function better than the jQuery version that tvanfosson posted which seems to do the swap only twice.

What standards peculiarities does it rely on?

insertBefore Inserts the node newChild before the existing child node refChild. If refChild is null, insert newChild at the end of the list of children. If newChild is a DocumentFragment object, all of its children are inserted, in the same order, before refChild. If the newChild is already in the tree, it is first removed.

Ionuț G. Stan