0

I am trying to make a automatic Javascript Slideshow based on w3 css that switches to manual when you hit the arrows. Besides this, in the beginning, if the previous or next arrows are not clicked, the slideshow will run for 2 loops.

When the page is loaded, the slideshow is in automated mode. That time, if we click the previous or next arrow, it should stop at the slide at that time. Instead it shows a white screen which looks ugly. I am adding the pause variable to try to acheive the pause function on clicking of arrows. Please tell what I am doing wrong. Note - I am very new to Javascript.

Below is my snippet -

var paused = false;
var myIndex = 0;
var counter = 0;
var maxLength = 0;
var loops = 2;
var interval = 1000; //for testing purposes
function carousel() {
  var x = document.querySelectorAll(".mySlides"); //using modern querySelectorAll
  maxLength = x.length * loops; //times 2 for two loops    

  //optimalization here - borrowing Array forEach to loop over node list
  Array.prototype.forEach.call(x, function(element) {
    element.style.display = "none";
  });

  counter++; //adding counter
  if (paused === false) { 
  if (myIndex >= x.length) {
    myIndex = 0
  }; //reset this to zero indexing
  x[myIndex].style.display = "block"; //show the slide
  if (counter <= maxLength) //ie counter <= 10, execute 
  {
    myIndex++; //add index with every pass
    setTimeout(carousel, interval);
    Array.prototype.forEach.call(x, function(element) {
     element.classList.remove("w3-animate-fading"); //remove the fading
   });  
  }
  }
  else
  {
    
  } 

}

carousel();

var slideIndex = 1;
showDivs(slideIndex);

function plusDivs(n) {
  showDivs(slideIndex += n);
  paused = true;
}

function showDivs(n) {
  var i;
  var x = document.getElementsByClassName("mySlides");
  if (n > x.length) {slideIndex = 1}    
  if (n < 1) {slideIndex = x.length}
  for (i = 0; i < x.length; i++) {
     x[i].style.display = "none";  
  }
  x[slideIndex-1].style.display = "block";  
}
.w3-content.w3-display-container {
  margin-top: 100px;
}
 
 button.w3-button.w3-display-left.w3-black {
  position: relative;
  left: -50px;
}
 
 button.w3-button.w3-display-right.w3-black {
  position: relative;
  right: -118px;
}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<div class="w3-content w3-display-container " style="max-width:150px">

  <div class="w3-display-container w3-animate-fading mySlides">
      <a href=""  target="_blank" title="slide1">
      <img class="" src="img01.jpg" style="width:100%">
      </a>
      <div class="w3-display-bottomleft w3-large  w3-container w3- 
  padding-16 w3-black">
        <a href="" target="_blank" title="slide1">Slide-1 (read more)</a>
    </div>
  </div>

  <div class="w3-display-container w3-animate-fading mySlides">
        <a href="" target="_blank" title="slide2">
    <img class="" src="img02.jpg" style="width:100%">
    </a> 
    <div class="w3-display-bottomright w3-large w3-container w3-padding-16     
  w3-black">
        <a href="" target="_blank" title="slide2">Slide-2 (more)</a>
    </div>
  </div>

  <div class="w3-display-container w3-animate-fading mySlides">
        <a href="" target="_blank" title="slide3">
    <img class="" src="img03.jpg" style="width:100%">
    </a>
        <div class="w3-display-topleft w3-large w3-container 
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide3">Slide-3 (read more)</a>
        </div>
  </div>  

  <div class="w3-display-container w3-animate-fading mySlides">
        <a href="" target="_blank" title="slide4">
    <img class="" src="img04.jpg" style="width:100%">
    </a>
        <div class="w3-display-topright w3-large w3-container 
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide4">Slide-4 (read more)</a>
        </div>
  </div>

  <div class="w3-display-container w3-animate-fading mySlides">
      <a href="" target="_blank" title="slide5">
      <img class="" src="img05.jpg" style="width:100%">
      </a>
        <div class="w3-display-middle w3-large w3-container   
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide5">Slide-5 (read more)</a>
        </div>
  </div>

  <button class="w3-button w3-display-left w3-black" 
  onclick="plusDivs(-1)">&#10094;</button>
      <button class="w3-button w3-display-right w3-black" 
  onclick="plusDivs(1)">&#10095;</button>

</div>
user20152015
  • 344
  • 2
  • 23
  • Please clarify which issue you are wanting fixed. From what I understand you want the slideshow to stop once they click the next arrow? – Jared Bledsoe Oct 09 '17 at 16:23
  • When the page is loaded, the slideshow is in automated mode. That time, if we click the previous or next arrow, it should stop at the slide at that time. Instead it shows a white screen which looks ugly. @JaredBledsoe – user20152015 Oct 09 '17 at 16:25
  • What if you used a setInterval() to swap pictures, and then once they clicked the arrow you used clearInterval()? – Jared Bledsoe Oct 09 '17 at 16:27
  • @JaredBledsoe Thanks for the comment. Since, I am new to Javascript, I am unable to do that. Can you modify the code as per your suggestion and see if it is solving the white page issue. – user20152015 Oct 09 '17 at 16:30

1 Answers1

1

Ok, so I changed your slideShow and here is the updated version, everything seems to be fully working now. https://jsfiddle.net/qhx93g1q/3/

//Changed index so 1 is actually first image, rather than starting at 0 index
var index = 1;
var paused = false;
var slideShow = [];
var counter = 0;
var maxLength = 0;
var loops = 2;
var interval = 2000; //for testing purposes

 var x = document.getElementsByClassName("slideShow");
 maxLength = x.length * loops; //times 2 for two loops
 
for (i=0; i<x.length; i++) {
  slideShow[i] = document.getElementsByClassName("slideShow")[i];
  slideShow[i].style.display = "none";
}

slideShow[0].style.display = "block";

var slides = setInterval(function() {
counter++; //adding counter
   if (counter <= maxLength) //ie counter <= 10, execute 
  {
    if (index < slideShow.length) {
  
    index++;
    showDivs();
    
    }
  else {
    index = 1;
    showDivs();
   }
  }
 else {
 }
 },interval);

function control(n) {
  clearInterval(slides);

  if (index+n > slideShow.length) {
    index = 1;
  }
  else if (index+n <= 0) {
    index = slideShow.length;
  }
  else {
    index += n;
  }
  showDivs();
}

function showDivs() {
  //Hide all slideShow elements, and then show only the targeted element
  for (i=1; i<=slideShow.length; i++) {
    slideShow[i-1].style.display = "none";
  }
  slideShow[index-1].style.display = "block";
}
.w3-content.w3-display-container {
  margin-top: 100px;
}
 
 button.w3-button.w3-display-left.w3-black {
  position: relative;
  left: -50px;
}
 
 button.w3-button.w3-display-right.w3-black {
  position: relative;
  right: -118px;
}

.fadeIn {
 animation-name: fadeIn;
 animation-duration: 2s;
 animation-fill-mode: forwards;
 animation-timing-function: ease-out;
}
@keyframes fadeIn {
 from {opacity:0;}
 to {poacity:1;}
}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>

<div class="w3-content w3-display-container " style="max-width:150px">

  <div class="w3-display-container fadeIn slideShow">
      <a href=""  target="_blank" title="slide1">
      <img class="" src="img01.jpg" style="width:100%">
      </a>
      <div class="w3-display-bottomleft w3-large  w3-container w3- padding-16 w3-black">
        <a href="" target="_blank" title="slide1">Slide-1 (read more)</a>
    </div>
  </div>

  <div class="w3-display-container fadeIn slideShow">
        <a href="" target="_blank" title="slide2">
    <img class="" src="img02.jpg" style="width:100%">
    </a> 
    <div class="w3-display-bottomright w3-large w3-container w3-padding-16     w3-black">
        <a href="" target="_blank" title="slide2">Slide-2 (more)</a>
    </div>
  </div>

  <div class="w3-display-container fadeIn slideShow">
        <a href="" target="_blank" title="slide3">
    <img class="" src="img03.jpg" style="width:100%">
    </a>
        <div class="w3-display-topleft w3-large w3-container 
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide3">Slide-3 (read more)</a>
        </div>
  </div>  

  <div class="w3-display-container fadeIn slideShow">
        <a href="" target="_blank" title="slide4">
    <img class="" src="img04.jpg" style="width:100%">
    </a>
        <div class="w3-display-topright w3-large w3-container 
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide4">Slide-4 (read more)</a>
        </div>
  </div>

  <div class="w3-display-container fadeIn slideShow">
      <a href="" target="_blank" title="slide5">
      <img class="" src="img05.jpg" style="width:100%">
      </a>
        <div class="w3-display-middle w3-large w3-container   
           w3-padding-16 w3-black">
        <a href="" target="_blank" title="slide5">Slide-5 (read more)</a>
        </div>
  </div>

  <button class="w3-button w3-display-left w3-black" onclick="control(-1)"><</button>
      <button class="w3-button w3-display-right w3-black" onclick="control(1)">></button>

</div>
Jared Bledsoe
  • 559
  • 5
  • 15
  • I added this because it's much easier to read/maintain than the code you posted, and the only thing you need to do is make it pause if you click the button (hint: clearInterval). I'll try to workout your issue with yours, but take a look at this because it is better organized. – Jared Bledsoe Oct 09 '17 at 18:48
  • Thanks for your effort @Jared Bledsoe . But as per my case, we need the arrow button to not only pause the automatic slide but also to display previous or next slide. I am trying to modify the code. But there seems to remain some glitch or the another. – user20152015 Oct 09 '17 at 19:28
  • I tried the clearinterval for your code and was successful in that. But am not able to use the arrows to go to previous / next slides. Please see my effort here - [link](https://codepen.io/anon/pen/gGzboZ) – user20152015 Oct 09 '17 at 20:23
  • So I did some cleaning up of the code and I got the final result here - https://jsfiddle.net/JaredBledsoe/qhx93g1q/ – Jared Bledsoe Oct 10 '17 at 02:52
  • Thanks @Jared Bledsoe Your code is working. However, we need one more functionality, that is slider should stop running automatically after 2 loops if the user does not click the arrows. I have forked your jsfiddle to a new jsfiddle here - [jsfiddle.net/62Lhr8mo](https://jsfiddle.net/62Lhr8mo/). Please see and if it is ok, please update your answer and I will accept it as correct answer – user20152015 Oct 10 '17 at 06:07
  • There is however a issue when I apply this code to my situation. It does not work properly with fade animation. Slide keeps fading in and out when the slide stops. So, I have to remove the fade animation for the code to function properly. Please see this pen applied with your code here - [codepen.io/anon/pen/gGeJVL](https://codepen.io/anon/pen/gGeJVL) – user20152015 Oct 10 '17 at 06:39
  • Also please remove the `let` as it is not supported in some mobile browsers. See - https://stackoverflow.com/a/38250355 – user20152015 Oct 10 '17 at 08:59
  • 1
    Ok, I fixed your animation issue. The pre-made animation you were using had a fadeOut effect towards the end, so I just made my own simple fadeIn animation, you can fine-tune it to get it to look exactly how you'd like. – Jared Bledsoe Oct 10 '17 at 19:27
  • Thanks @Jared Bledsoe. The problem was with the animation as you have rightly found. The w3 school animation from the w3 code had infinitely running animation due to which the fading was going on even after the slide stopped / paused. – user20152015 Oct 12 '17 at 12:39