3
votes

I have a gallery with thumbnails and when the thumbnails are clicked the current image fades out and the new image fades in.

However, I want to stop multiple clicks, so the image has to fade out completely before being able to click a new thumbnail.

How can I do this with the code below?

Many thanks,

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>TEST</title>
<script type='text/javascript' src='jquery-1.9.1.js'></script>

<style type='text/css'>
#imageWrap{
position:relative;
overflow:hidden;
height:534px;
width:800px;
}
.next{
display:none;
}
#imageWrap img{
width: 800px;
position: absolute;
top: 0;
left: 0;
background-color: #000;
}
</style>

<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
$('.thumbnail').on('click',function(){
$('#imageWrap').append('<img src="' + $(this).attr('src') + '" class="next" />');
$('#imageWrap .active').fadeOut(5500);
$('#imageWrap .next').fadeIn(4000, function(){
    $('#imageWrap .active').remove();
    $(this).addClass('active');
});

});
});//]]>  

</script>

</head>
<body>
<img src="dimming/1.jpg" class="thumbnail" alt="A" width="40" height="40"/>
<img src="dimming/2.jpg" class="thumbnail" alt="B" width="40" height="40"/>
<img src="dimming/C.jpg" class="thumbnail" alt="C" width="40" height="40"/>
<img src="dimming/D.jpg" class="thumbnail"alt="D" width="40" height="40"/>
<img src="dimming/E.jpg" class="thumbnail" alt="E" width="40" height="40"/>

<div id="imageWrap">
    <img src="dimming/C.jpg" alt="Main Image" width="800" height="534" class="active" />
</div>
</body>
</html>
2
I actually do this in a really simple way. On click I add a div to the image container, which is positioned absolutely inside the container. And when all animations are done, I just remove this layer. It can be done in a number of ways actually, but this way I don't have to bother with removing/adding listeners. - Eduárd Moldován
Eduard, do you have an example of this, sounds interesting. - Darren Riches

2 Answers

5
votes

By adding a boolean flag whose status you can check before deciding what to do:

// Are we in the middle of an animation?
var currentlyAnimating = false;

$('.thumbnail').on('click',function(){
    if (currentlyAnimating) {
        return;
    }

    currentlyAnimating = true;

    $('#imageWrap').append('...');
    $('#imageWrap .active').fadeOut(5500);
    $('#imageWrap .next').fadeIn(4000, function(){
        $('#imageWrap .active').remove();
        $(this).addClass('active');
        currentlyAnimating = false;
    });
});

Of course you can also make this check by querying the status of the DOM or jQuery's effects queue for the elements in question, but IMO it is much simpler and cleaner with a localized solution like the above.

1
votes

You can check that #imageWrap .next and #imageWrap .active are not animated using the :animated selector.

$('.thumbnail').on('click',function(){
   if(!$("#imageWrap .next, #imageWrap .active").is(":animated")){
      $('#imageWrap').append('<img src="' + $(this).attr('src') + '" class="next" />');
      $('#imageWrap .active').fadeOut(5500);
      $('#imageWrap .next').fadeIn(4000, function(){
          $('#imageWrap .active').remove();
          $(this).addClass('active');
      });//this was missing      
   }
});