M1X
M1X

Reputation: 5374

Swap div position with animation

How to swap div position when clicked only with the first div in stack. So when div 2 or 3 is clicked it will swap with the first child of parent in DOM and when the first child of parent in DOM is clicked nothing should happen.

This is my fiddle: http://jsfiddle.net/exc5m046/

HTML

<div id="container">
    <div id="one" class="move">div 1</div>
    <div id="two" class="move">div 2</div>
    <div id="three" class="move">div 3</div>
</div>

CSS

#container {
    width: 200px;
    color:#fff;
    position: relative;
    text-align:center;
}
#container div {
    position: relative;
    margin:10px;
    background:#ff00ab;
    padding:5px;
    border-radius:3px;
    text-align:center;
    display:inline-block;
}

jQuery

var animating = false;

$('#container').on('click', '.move', function () {

    var clickedDiv = $(this).closest('div'),

    prevDiv = clickedDiv.prev(),
    distance = clickedDiv.offset().left - prevDiv.offset().left;

    if (prevDiv.length) {
        animating = true;
        $.when(clickedDiv.animate({
           left: -distance
        }, 2000),
        prevDiv.animate({
            left: distance
        }, 2000)).done(function () {
            prevDiv.css('left', '0px');
            clickedDiv.css('left', '0px');
            clickedDiv.insertBefore(prevDiv);
            animating = false;
        });
    }
});

Upvotes: 2

Views: 10302

Answers (3)

LcSalazar
LcSalazar

Reputation: 16839

EDITTED:

To swap the clicked div only with the first element, you have to change the script. The prevDiv variable is selecting the previous sibiling the apply the switch, but you want to change it to:

prevDiv = $("#container > :first-child")

so it always selects the first child of the container.


Then, add the condition that the clicked element cannot be the first one:

if (!clickedDiv.is(":first-child")) {


Finally, to swap correctly, place the prevDiv at the place where the clicked div was, and set the clickedDiv to be the first child with prependTo(''):

prevDiv.insertBefore(clickedDiv);
clickedDiv.prependTo("#container");

And, now, you're good to go: http://jsfiddle.net/exc5m046/3/

Upvotes: 4

guest271314
guest271314

Reputation: 1

Edit, updated

Try

html

<!-- removed class `first` from element at index 0 -->
<div id="container">
    <div id="one" class="move">div 1</div>
    <div id="two" class="move">div 2</div>
    <div id="three" class="move">div 3</div>
</div>

js

var animating = false;

$('#container').on('click', '.move', function () {

    var clickedDiv = $(this).closest('div'),

        // adjusted `prevDiv` to `$(".move").eq(0)`
        prevDiv = $(".move").eq(0),
        distance = clickedDiv.offset().left - prevDiv.offset().left;

    if (/*!clickedDiv.is(".first") &&*/ prevDiv.length) {
        animating = true;
        $.when(clickedDiv.animate({
           left: -distance
        }, 2000),
        prevDiv.animate({
            left: distance
        }, 2000)).done(function () {
            prevDiv.css('left', '0px');
            clickedDiv.css('left', '0px');
            // changed `clickedDiv.insertBefore(prevDiv);` to 
            // `clickedDiv.prependTo("#container");`
            clickedDiv.prependTo("#container");
            animating = false;
        });
    }
});

http://jsfiddle.net/exc5m046/14/

See http://api.jquery.com/prependTo/

Upvotes: 1

user32342534
user32342534

Reputation: 145

Try

$('#container div').on('click', '.move', function () {
  if ( $( this ).index() == 0 ) {
    return
  } else {
    //...code
  }
}

This triggers your code only, if the div is not the first element in the parent #container.

Upvotes: 0

Related Questions