1

I have an automatic slideshow that works fine. However, I would like to be able to vary the speed for some of the slides Here is the code:

var slideIndex = 0;
showSlides();

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  for (i = 0; i < slides.length; i++) {
      slides[i].style.display = "none"; 
  }
  slideIndex++;
  if (slideIndex > slides.length) {slideIndex = 1} 
  slides[slideIndex-1].style.display = "block"; 
  setTimeout(showSlides, 2000); // Change image every 2 seconds
}

Thanks

Mike Donkers
  • 3,589
  • 2
  • 21
  • 34
user2720970
  • 284
  • 1
  • 3
  • 17
  • What is your question? – Lam Pham Jan 26 '18 at 10:43
  • I recommend setInterval instead of for in which showSlider function. Because for loop's performance depends on the client's cpu. That means your slider will be shown different in each computer. – Fatih TAN Jan 26 '18 at 10:44
  • The current timeout is 2 seconds for #mySlides. I would like to have another slide timeout to 4 seconds. – user2720970 Jan 26 '18 at 10:52
  • Have you thought about adding a data property on the elements which contains their timeout length? – DBS Jan 26 '18 at 10:55

4 Answers4

2

You could add a data attribute to your elements containing the timeout for each slide, and then read it when displaying the slide.

E.g. (using your code)

var slideIndex = 0;
showSlides();

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
  slideIndex++;
  if (slideIndex > slides.length) {
    slideIndex = 1
  }
  slides[slideIndex - 1].style.display = "block";
  setTimeout(showSlides, $(slides[slideIndex - 1]).data("time")); // Grab the data-time from the element we're using
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mySlides" data-time="500">Test 1</div>
<div class="mySlides" data-time="2000">Test 2</div>
<div class="mySlides" data-time="5000">Test 3</div>
<div class="mySlides" data-time="500">Test 4</div>
DBS
  • 9,110
  • 4
  • 35
  • 53
2

I put your code into an almost-class.

The Fiddle:
https://jsfiddle.net/4bjcdftq/

The Snippet:

var iSlider = {
  slideIndex: null,
  prevSlideIndex: null,
  slides: null,
  defaultDuration: 2000,

  initSlides: function(){
    this.slides = document.getElementsByClassName("iSlide");
    for( var i = 0; i < this.slides.length; i++ ){
      this.slides[i].style.display = "none"; 
    }
    this.prevSlideIndex = null;
    this.slideIndex = -1;
  },

  showSlides: function(){
    if( this.prevSlideIndex != null )  this.slides[ this.prevSlideIndex ].style.display = "none";
    this.slideIndex = ( this.slideIndex + 1 + this.slides.length ) % this.slides.length;
    this.slides[ this.slideIndex ].style.display = "block";
    this.prevSlideIndex = this.slideIndex;
    var duration = +( this.slides[ this.slideIndex ].getAttribute('data-duration') || this.defaultDuration );
    setTimeout( this.showSlides.bind( this ), duration ); // Change image every 2 seconds
  }
};

iSlider.initSlides();
iSlider.showSlides();
    <div class="iSlide" data-duration="500">111</div>
    <div class="iSlide" data-duration="">222</div>
    <div class="iSlide" data-duration="4000">333</div>
    <div class="iSlide" data-duration="">444</div>
biziclop
  • 14,466
  • 3
  • 49
  • 65
  • This is the best solution so far, the only improvement would be that an IIFE could prevent slideIndex, preSlideIndex, slides and defaultDuration from being exposed to the public – Pavlo Jan 26 '18 at 11:19
  • @Pavlo: You are right, but I liked the original iMac. :) http://4827-presscdn.pagely.netdna-cdn.com/wp-content/uploads/2012/05/Original-iMac.jpg – biziclop Jan 26 '18 at 11:42
0

You can add an attribute to your slides data-timeout

I.E:

<div class='mySlides' data-timeout='2000'>Slide 1</div>

And then every loop get the specific timeout for a slide.

var slideIndex = 0;

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
  slideIndex++;
  if (slideIndex > slides.length) {
    slideIndex = 1
  }
  slides[slideIndex - 1].style.display = "block";
  var timeout = slides[slideIndex - 1].getAttribute('data-timeout');
  console.log(timeout);
  setTimeout(showSlides, timeout);
}

showSlides();
<div class='mySlides' data-timeout='2000'>Slide 1</div>
<div class='mySlides' data-timeout='3000'>Slide 2</div>
<div class='mySlides' data-timeout='4000'>Slide 3</div>
halfer
  • 19,824
  • 17
  • 99
  • 186
Ele
  • 33,468
  • 7
  • 37
  • 75
0

You can do it like that

var slideIndex = 0;
showSlides();

function showSlides() {
  var i;
  var time = 200;
  var slides = document.getElementsByClassName("mySlides");
  for (i = 0; i < slides.length; i++) {
      slides[i].style.display = "none"; 
      if(i == 2){
        time = 500;
      }else{
        time = 200
      }
  }
  slideIndex++;
  if (slideIndex > slides.length) {slideIndex = 1} 
  slides[slideIndex-1].style.display = "block"; 
  setTimeout(showSlides, time); // Change image every 2 seconds
}

On this example i change the time to 500ms for the slide 2.