Search code examples
javascriptjqueryanimation

Why doesn't my element 'swap' animation code show the first element again after second element is hidden?


OK, its not a toggle() as such. This code is supposed to work like a slider. 1 Div is showing, you click a button, and the next div shows, click another button, and the first div shows.

This works so far, but it doesn't work going backward. So the button works to show the 2nd Div, but hitting the 'less' button I made just makes the second div disappear and the 1st remains hidden.

$('.more').click(function() {
    $('.c1')
        .animate({ left: "-400px" }, 600)
        .delay(300, function() {
            $('.c2').animate({ left: "0px" }, 600); 
        }
    );
});

$('.less').click(function() {
    $('.c2')
        .animate({ left: "400px" }, 600)
        .delay(300, function(){
            $('.c1').animate({ left: "0px" }, 600); 
        }
    );
});
.container {
    width: 400px;
    position: relative;
    height: 200px;
    overflow: hidden;
}

.c1,.c2 {
    width: 400px;
    height: 200px;
    position: absolute;
}

.c1 {
    background: green;
    left: 0;
}

.c2 {
    background: red;
    left: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="container">
    <div class="c1">
            <a class="more" href="#more">More</a>
    </div>
    <div class="c2">
            <a class="back" href="#less">Less</a>
    </div>
</div>

What am I missing? And how could I do this so that I'm basically not repeating the same code twice?


Solution

  • You have the wrong idea about .delay. From the jQuery documentation for that function:

    Description: Set a timer to delay execution of subsequent items in the queue.

    And its parameters are: duration [, queueName].

    Also, see this from Rory McCrossan's answer to Why doesn't my jQuery delay() function work correctly?:

    The delay() function only applies to actions queued on the element

    So I think your best choice is, as nicolast said in a now-deleted answer, use the callbacks. Here's a JSFiddle demo showing it working. And the final code is:

    $('.more').click(function() {
        $('.c1')
            .animate({ left: "-400px" }, 600, function() {
                $('.c2').animate({ left: "0px" }, 600);
            }
        );
    });
    
    $('.less').click(function() {
        $('.c2')
            .animate({ left: "400px" }, 600, function(){
                $('.c1').animate({ left: "0px" }, 600);
            }
        );
    });