1

I have a slideshow of 5 images, every couple seconds. It's supposed to go to the next image, and loop.

What is currently occurring is the first image shows up, then transitions to the next. When the next appears, it flashes back to the first image. Then it goes to the third image as it should in the series, but flashes back to the first image again. This continues all the way through to the fifth image.

But once it cycles through to the first image again (after going through all five) everything works fine from there on. Each image sits for 3 seconds and then moves on, no jumping back to image one or anything.

Here's the code I'm using.

Html:

<div id="slideshow">
   <div>
     <img src="Images/1.gif">
   </div>
   <div>
     <img src="Images/2.gif">
   </div>
   <div>
     <img src="Images/3.gif">
   </div>
   <div>
     <img src="Images/4.gif">
   </div>
   <div>
     <img src="Images/5.gif">
   </div>
</div>

CSS:

#slideshow { 
    clear: both;
    margin: 50px auto; 
    position: relative; 
    max-width: 960px; 
    height: 643px; 
    padding: 10px; 
    box-shadow: 0 0 20px rgba(0,0,0,0.4); 
}

#slideshow > div { 
    position: absolute; 
    top: 10px; 
    left: 10px; 
    right: 10px; 
    bottom: 10px; 
}

#slideshow img {
    max-width: 100%;    
}

JS:

$("#slideshow > div:gt(0)").hide();

setInterval(function() { 
  $('#slideshow > div:first')
    .fadeOut(800)
    .next()
    .fadeIn(800)
    .end()
    .appendTo('#slideshow');
},  3000);

The actual site I'm putting together is here so you can see it in action:

schmelzerwedding.com

Any help to make it not jump back like that would be greatly appreciated. Thank you!

R. Arnone
  • 423
  • 4
  • 15
  • 1
    Can you please insert a jsfiddle? – Pascal Goldbach May 30 '16 at 15:33
  • I wouldn't do `appendTo()` every time if I were you. Seems unnecessarily complex and performance heavy. Just keep track of which slide you're on and increase the number each time until you reach the end at which point you set it to 0 again. – powerbuoy May 30 '16 at 15:40

3 Answers3

1

Like I mentioned in my comment I think the use of appendTo() may be the culprit. I also believe it's not the best thing to do performance wise.

Here's a version that simply keeps track of which slide we're on and increases the number.

(function () {
  var slideshow = document.getElementById('slideshow');
  var slides = slideshow.getElementsByTagName('img');
  var currSlide = 0;
  var numSlides = slides.length;
  
  // Set first slide to active
  slides[currSlide].classList.add('active');
  
  setInterval(function () {
    slides[currSlide].classList.remove('active');
    currSlide = (currSlide + 1) >= numSlides ? 0 : currSlide + 1;
    slides[currSlide].classList.add('active');
  }, 2000);
})();
#slideshow {
  position: relative;
  width: 200px;
  height: 200px;
}

#slideshow img {
  opacity: 0;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  transition: opacity .2s ease-out;
}

#slideshow img.active {
  opacity: 1;
}
<div id="slideshow">
<img src="http://placehold.it/199x199">
<img src="http://placehold.it/200x200">
<img src="http://placehold.it/201x201">
<img src="http://placehold.it/202x202">
</div>

Edit: If you (for some reason) don't want to use pure JS, here's the same code in jQuery:

(function () {
    var slideshow = $('#slideshow');
    var slides = slideshow.find('> *');
    var currSlide = 0;
    var numSlides = slides.length;

    slides.eq(currSlide).addClass('active');

    setInterval(function () {
        slides.eq(currSlide).removeClass('active');
        currSlide = (currSlide + 1) >= numSlides ? 0 : currSlide + 1;
        slides.eq(currSlide).addClass('active');
    }, 200);
})();
powerbuoy
  • 12,460
  • 7
  • 48
  • 78
0

Using jQuery:

//Just for demo - takes a few secs to load the images
setTimeout(function(){
  $('#ld').hide();
},500);


var cnt = 0;
$("#slideshow > div:gt(0)").hide();
setTimeout(showSlide, 2000);

function showSlide() {
  cnt++;
  cnt = (cnt>3)?0:cnt;
  $("#slideshow > div").fadeOut();
  $("#slideshow > div:eq("+cnt+")").fadeIn();
  setTimeout(showSlide, 2000);
}
#slideshow {clear:both;margin:50px auto;position:relative;max-width:960px;height:643px;padding:10px;box-shadow:0 0 20px rgba(0, 0, 0, 0.4);}

#slideshow > div {position:absolute;top:10px;left:10px;right:10px;bottom:10px;}

#slideshow img {max-width:100%;}

/* For Demo Only */
#ld{position:absolute;top:10%;left:20%;font-size:5rem;text-shadow:5px;z-index:2;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="slideshow">
  <div><img src="http://placekitten.com/550/200"></div>
  <div><img src="http://placekitten.com/548/200"></div>
  <div><img src="http://placekitten.com/550/202"></div>
  <div><img src="http://placekitten.com/548/202"></div>
</div>
<div id="ld">Loading . . . </div>
cssyphus
  • 37,875
  • 18
  • 96
  • 111
  • Downvote for hard-coded number of slides, JavaScript animations (as opposed to CSS transitions), nested `setTimeout` (with unnecessary anonymous function) instead of (the cleaner (imo)) `setInterval`, obtrusive "loading" HTML as well as unnecessary use of jQuery (imo). – powerbuoy May 31 '16 at 19:37
  • @powerbuoy When you disagree with a proposed solution, especially to the extent you do here, it is most community-minded to present your own improved solution (1) so that others can learn from you, (2) to provide a better solution to the OP, and (3) to get a few upvotes for yourself. *Otherwise, what exactly are you accomplishing other than trying to make others feel like crap?* – cssyphus May 31 '16 at 22:43
  • @KyleSchmelzer I just looked at your site. Congrats are in order. :) You are also getting some stuttering at the beginning of the slide show because the images are not fully loaded when the slideshow begins. Try [wrapping the code](http://stackoverflow.com/questions/10863277/delay-some-jquery-function-until-all-images-are-loaded-completely) in a `$(window).load(){ //all slideshow code here });` and that should help. [See this link for more](http://stackoverflow.com/questions/10863277/delay-some-jquery-function-until-all-images-are-loaded-completely) – cssyphus Jun 01 '16 at 04:42
  • I meant no offense. I hate it when I get downvoted and the person doesn't even have the courtesy to explain why. Perhaps I sounded a bit harsh, and if so I do apologize. I did leave my own solution though. – powerbuoy Jun 01 '16 at 08:50
  • 1
    @powerbuoy I totally agree with you, and I should actually have thanked you for having the integrity to say why you downvoted. Whups, I didn't notice the other answer was yours. Apologies - will review/upvote accordingly. By the way, (a) the OP asked for either js or jQuery and a js solution was already provided, and (b) setInterval has its drawbacks [as explained here](http://stackoverflow.com/a/731625/1447509). CSS transitions are a better solution, though, as you point out. – cssyphus Jun 01 '16 at 16:13
  • @powerbuoy Thanks also for this thread as it prompted me to re-read the setTimeout example and improve my own answer accordingly. *That's why I hang out on SO - not because I'm an expert, but because by helping others I'm improving also. As the old saying goes, the best way to learn is to teach.* – cssyphus Jun 01 '16 at 16:22
  • Thanks Gibberish, this was the only suggestion that ended up working as I needed it too. Appreciate you actually reading what I asked for, and solving my problem as I asked it to be. Marked you as the person who solved this, thanks! Also thanks on the congrats! – Kyle Schmelzer Jun 02 '16 at 23:57
-1

Boostrap cannot pickup jQuery right away, try changing the order that they are called in the head.

Martin Hugo
  • 184
  • 1
  • 1
  • 10