Prabhu
Prabhu

Reputation: 21

How to slide different div top to down with jQuery animation?

I would like to slide first div to last div synchronize with animation. could you please help me on jquery.

$(function() {
    $('#switch').click(function() {
        $('#one').animate({top:$("#three").offset().top}); 


    });
});

jsfiddle

Upvotes: 1

Views: 184

Answers (3)

Tahir Ahmed
Tahir Ahmed

Reputation: 5737

I am not sure what exactly you are looking for but I think below is what you are trying to do:

Snippet:

$(function() {
    var squares = $('.square');
    var numSquares = squares.length;
    var currPositions = [];
    squares.each(function(index){
        currPositions[index] = $(this).offset().top;
        $(this).data('iterator', index);
    });
    $('#switch').click(function() {
        squares.each(function(index){
            $(this).data('iterator', parseInt($(this).data('iterator')) - 1);
            if (parseInt($(this).data('iterator')) < 0) $(this).data('iterator', numSquares - 1);
            $(this).animate({ top: currPositions[$(this).data('iterator')] });
        });
    });
});
html, body { margin: 0; padding: 0; }
#one {
    position:absolute;
    width:50px;
    height:50px;
    background:blue;
}
#two {
    position:absolute;
    top: 50px;
    width:50px;
    height:50px;
    background:red;
}
#three {
    position:absolute;
    top: 100px;
    width:50px;
    height:50px;
    background:purple;
}
#four {
    position:absolute;
    top:150px;
    width:50px;
    height:50px;
    background:orange;
}
.square {
    text-align:center;
    line-height:50px;
    color:white;
    font-weight:bold;
}
.clear {
    clear:both;
}
#switch {
    margin-left: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="one" class="square">1</div>
<div id="two" class="square"> 2</div>
<div id="three" class="square"> 3</div>
<div id="four" class="square"> 4</div>
<div class="clear"></div>
<br />
<button id="switch">switch positions</button>

Hope this helps.

Details:

  • For this solution to work, I have used position: absolute; in CSS for all the .square elements i.e. on #one, #two, #three and #four elements.
  • I have also applied top values with an increment of 50px on each of those elements. The value 50px comes from taking the height of boxes into account.
  • In JavaScript, the default positions are first calculated and put inside a currPositions array respective of their index values.
  • Then there is this $(this).data(...) helper method of jQuery used to place an iterator inside of each of the .square jQuery objects.
  • This iterator is then used to decrement one by one on every element and it keeps iterating through the currPositions array previously created, to get the destination values for any current .square element to animate to.

Hope you find it useful.

Upvotes: 1

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34199

Your first item is not located at the top of the page and you ignore it while calculating positions. There is a little gap - body has margin equal to 8px.

I.e., when you calculate position of block 3, you do:

$('#one').animate({top:$("#three").offset().top}); 

$("#three").offset().top is equal to 108 because 8 of them is margin, 100 of them is a real position. It moves block to top = 108, and with margin, it becomes 116 - 8 pixels lower than you need. Respectively, blocks 2 and 3 move 8 pixels above than you need.

You need to substract the position of first block in order to get a relative position. Here is the code:

$(function() {
    $('#switch').click(function() {
        $('#one').animate({top:$("#three").offset().top - $("#one").offset().top}); 
        $('#two').animate({bottom:$("#two").offset().top - $("#one").offset().top});
        $('#three').animate({bottom:$("#two").offset().top - $("#one").offset().top});     
    });
});

Check this JSFiddle demo out.

Update:
Anyway, in my opinion, this approach is incorrect. You have HTML blocks which have relative positions. Manipulating with their positions directly is a bad approach. Moreover, it has difficult calculations and you can easily become confused if you have more than 4 items or if you have complex CSS rules.

The best approach is just swap their positions in DOM. It is DOM-friendly, CSS-friendly, cross-browser. It is easily readable and maintainable. Let browser do all the work for you! With it, you are also able to add any number of items without changing the code.

Check this JS function:

$(function() {    
    $('#switch').click(function() {  
        var firstItem = $(".square:first"); // Take the first item
        firstItem.fadeOut('slow', function() { // Hide it. Then...
            firstItem.parent().append(firstItem); // Add it to the end
            firstItem.fadeIn(); // Show it
        });
    });
});

Full example with fading at JSFIddle.

You can also use slideUp, slideDown functions in order to make it look better.

Full example with sliding at JSFIddle.

Without animation it would be even shorter:

$(function() {    
    $('#switch').click(function() {  
        var firstItem = $(".square:first"); // Take the first item
        firstItem.parent().append(firstItem); // Add it to the end. Profit!
    });
});

Upvotes: 2

Rohan Kumar
Rohan Kumar

Reputation: 40639

Due to little information, I've created a demo four you please try,

HTML

<div style="position:relative;">
    <div id="one" class="square">1</div>
    <div id="two" class="square">2</div>
    <div id="three" class="square">3</div>
    <div id="four" class="square">4</div>
</div>
<div class="clear"></div>
<br />
<button id="switch">switch positions</button>

CSS

#one {
    top:0;
    background:blue;
}
#two {  
    top:50px;
    background:red;
}
#three {
    top:100px;
    background:purple;
}
#four {
    top:150px;
    background:orange;
}
.square {
    text-align:center;
    line-height:50px;
    color:white;
    font-weight:bold;
    width:50px;
    height:50px;
    position:absolute;
}
.clear {
    clear:both;
}
#switch{
    position:relative;
    left:150px;
}

Jquery

$(function () {
    $('#switch').click(function () {
        var t = ($('.square').length-1) * $('.square:first').height();
        $('.square:first').animate({
            top: t
        }, function () {
            $('.square:gt(0)').each(function (i, v) {
                var $el = $('.square:eq(' + (i + 1) + ')');
                $el.animate({
                    top: i * $el.height()
                })
            });
            o = $(this).clone();
            $(this).remove();
            o.insertAfter($('.square:last'));
        });
    });
});

$(function () {
    $('#switch').click(function () {
        var t = ($('.square').length-1) * $('.square:first').height();
        $('.square:first').animate({
            top: t
        }, function () {
            $('.square:gt(0)').each(function (i, v) {
                var $el = $('.square:eq(' + (i + 1) + ')');
                $el.animate({
                    top: i * $el.height()
                })
            });
            o = $(this).clone();
            $(this).remove();
            o.insertAfter($('.square:last'));
        });
    });
});
#one {
    top:0;
    background:blue;
}
#two {  
    top:50px;
    background:red;
}
#three {
    top:100px;
    background:purple;
}
#four {
    top:150px;
    background:orange;
}
.square {
    text-align:center;
    line-height:50px;
    color:white;
    font-weight:bold;
    width:50px;
    height:50px;
    position:absolute;
}
.clear {
    clear:both;
}
#switch{
    position:relative;
    left:150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative;">
    <div id="one" class="square">1</div>
    <div id="two" class="square">2</div>
    <div id="three" class="square">3</div>
    <div id="four" class="square">4</div>
</div>
<div class="clear"></div>
<br />
<button id="switch">switch positions</button>

You can also try Swap Plugin.

Upvotes: 2

Related Questions