Search code examples
javascriptjqueryimagehideslideshow

How do I hide previous slide in a simple jQuery slideshow?


I'm creating an online portfolio for my girlfriend and for that a simple slideshow of images with fade transitions. I want to be able to "hide" the previous "last-active" slide, when a new "active" one is shown.

I've modified the slideshow provided here (http://jonraasch.com/blog/a-simple-jquery-slideshow), so instead of an automatic cycle, it is controlled by 'prev / next' buttons. That all works great. Contrary to the above example, I need to have different sized images in the slideshow.

Problem: The way the slideshow works, like a stack of images, I'm seeing the previous image behind the current "active" one. E.g. when switching between a vertical (portrait) image and a horizontal (landscape) image, i can see the landscape one behind the portrait one.

I've tried the jQuery .hide() method within the $nextSlide() function, but not sure if that's the right way to do it. I'm a complete javascript and jQuery novice.

HTML:

<div id="slideshow">
    <div class="active">
        <img src="horizontal.jpg">
    </div>

    <div>
        <img src="vertical.jpg">
    </div>

</div>

<div id="controls">
<span class="control-prev">prev</span> / <span class="control-next">next</span>
</div>

CSS:

#slideshow {
    position:relative;
    height:400px;
}

#slideshow DIV {
    position:absolute;
    top:0;
    left:0;
    z-index:8;
    opacity:0.0;
    height: 400px;
    background-color: white;
}

#slideshow DIV.active {
    z-index:10;
    opacity:1.0;
}

#slideshow DIV.last-active {
    z-index:9;
}

#slideshow DIV IMG {
    height: 350px;
    display: block;
    border: 0;
    margin-bottom: 10px;
}

JavaScript:

function nextSlide() {
    var $active = $('#slideshow DIV.active'); 
    if ( $active.length == 0 ) $active = $('#slideshow DIV:last'); 


    var $next =  $active.next().length ? $active.next() 
        : $('#slideshow DIV:first');


    $active.addClass('last-active');
    $next.css({opacity: 0.0})
        .addClass('active')
        .animate({opacity: 1.0}, 300, function() {
            $active.removeClass('active last-active');
        });
}
$(".control-next").click(function(){
    nextSlide();
    });

´´´

The goal is to have a slideshow that doesn't show the images like a stack. I bet the solution is very simple, but I can't work it out.

Solution

  • After removing the active and last-active classes from your div... reset their opacity back to 0.0 so next time it will animate (fade in) again:

    function nextSlide() {
        var $active = $('#slideshow DIV.active'); 
        if ( $active.length == 0 ) $active = $('#slideshow DIV:last'); 
    
    
        var $next =  $active.next().length ? $active.next() 
            : $('#slideshow DIV:first');
    
    
        $active.addClass('last-active');
        $next.css({opacity: 0.0})
            .addClass('active')
            .animate({opacity: 1.0}, 300, function() {
                $active.css({opacity: 0.0})
                       .removeClass('active last-active');
            });
    }
    

    If you also want it to fade-out, rather than just going to opacity 0... use the following:

    $next.css({opacity: 0.0})
                .addClass('active')
                .animate({opacity: 1.0}, 300, function() {
                    $active.css({opacity: 1.0})
                           .animate({opacity: 0.0}, 300, function(){
                              $active.removeClass('active last-active')
                           });
                });