-1

I found two codes online from w3schools.com and I have been trying to combine them into a working code. I have been at it for two days and for the life of me cannot figure out how to make the dots work with the images. The issue I have noticed is that the dots when clicked start to throw the images off sync and they start speeding up. Im at a bit of a loss here. Any help would be appreciated. Here is a "working" example: JSFiddle

<!DOCTYPE html>
<html>
<style>
#slideshow_container {display: inline-block; max-width: 800px; max-height: 320px;}
#slideshow_nav {position: absolute; z-index: 2; top: 0px; width: 800px; height: 320px;}
.mySlides {display: none; width: 800px; height: 320px;}
.w3-center {top: -40px; left: 0px;}
#arrow-left {text-align: right;}
#arrow-right {text-align: left;}
.dots {z-index: 3; height: 13px; width: 13px; padding: 0; display: inline-block; border-radius: 100%; color: #FFF; background: #ffffff; border: 1px solid #000000;}
.dots-red {z-index: 3; height: 13px; width: 13px; padding: 0; display: inline-block; border-radius: 100%; color: #FFF; background: #ff0000; border: 1px solid ff0000;}
#arrow-left, #arrow-right, .dots {cursor: pointer; color: #F00;}
</style>

<body>
 <div id="slideshow_container" onmouseover="stop()" onmouseout="start()">
  <img class= "mySlides" src= "https://appraw.com/static/previews/downloads/d/z/k/p-desert-zK6WoOEYks-1.jpg">
  <img class= "mySlides" src= "https://www.stockvault.net/data/2007/03/01/102413/preview16.jpg">
  <img class= "mySlides" src= "https://image.shutterstock.com/image-photo/da-lat-vietnam-sun-rise-600w-440121226.jpg">

   <table id="slideshow_nav" width="800" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="middle" width="40px"><div id="arrow-left" onclick= "plusDivs(-1) ">&#10094;</div></td>
    <td align="center" valign="bottom">
        <span class="dots" id="dot1" onclick= "currentDiv(1) "></span>
        <span class="dots" id="dot2" onclick= "currentDiv(2) "></span>
        <span class="dots" id="dot3" onclick= "currentDiv(3) "></span>
     </td>
    <td valign="middle" width="40px"><div id="arrow-right" onclick= "plusDivs(1) ">&#10095;</div></td>
  </tr>
</table>

<script>

function stop() 
{document.getElementById("slideshow_container").stop;}
function start() 
{document.getElementById("slideshow_container").start;}

var myIndex = 0;
showDivs(myIndex);
function plusDivs(n) {showDivs(myIndex += n);}
function currentDiv(n) {showDivs(myIndex = n);}
function showDivs(n) {
 var i;
 var x = document.getElementsByClassName("mySlides");
 var dots = document.getElementsByClassName("dots");
  if (n > x.length) {myIndex = 1}    
  if (n < 1) {myIndex = x.length}
  for (i = 0; i < dots.length; i++) {
    x[i].style.display =  "none"; 
    dots[i].className = dots[i].className.replace( "dots-red"," ");
   }
    myIndex++;
     if (myIndex > x.length) {myIndex = 1}    
      x[myIndex-1].style.display = "block";  
      dots[myIndex-1].className += " dots-red"; 
     setTimeout(showDivs, 2000);
    }
</script>

</body>
</html> 

1 Answers1

1

You need to clear the timeout using clearTimeout() each time showDiv() is called.

This is because when you click a dot, it'll call showDiv() which will create a new timeout that's concurrent with the one that already exists, and those timeouts call showDiv themselves, to keep their interval going.

So by clearing the current timeout which is getting ready to call showDiv, we reset the interval loop.

function stop() {
  document.getElementById("slideshow_container").stop;
}

function start() {
  document.getElementById("slideshow_container").start;
}

var myIndex = 0;


function plusDivs(n) {
  showDivs(myIndex += n);
}

function currentDiv(n) {
  showDivs(myIndex = n);
}

let timeout; // Declare the variable we'll save our timeout to outside the function that sets the timeout
function showDivs(n) {
  clearTimeout(timeout); // Clear the timeout each time the function is called
  var i;
  var x = document.getElementsByClassName("mySlides");
  var dots = document.getElementsByClassName("dots");
  if (n > x.length) {
    myIndex = 1
  }
  if (n < 1) {
    myIndex = x.length
  }
  for (i = 0; i < dots.length; i++) {
    x[i].style.display = "none";
    dots[i].className = dots[i].className.replace("dots-red", " ");
  }
  myIndex++;
  if (myIndex > x.length) {
    myIndex = 1
  }
  x[myIndex - 1].style.display = "block";
  dots[myIndex - 1].className += " dots-red";
  timeout = setTimeout(showDivs, 2000); // Save the timeoutID to the variable we declared to be able to reset it
}

showDivs(myIndex);
#slideshow_container {
  display: inline-block;
  max-width: 800px;
  max-height: 320px;
}

#slideshow_nav {
  position: absolute;
  z-index: 2;
  top: 0px;
  width: 800px;
  height: 320px;
}

.mySlides {
  display: none;
  width: 800px;
  height: 320px;
}

.w3-center {
  top: -40px;
  left: 0px;
}

#arrow-left {
  text-align: right;
}

#arrow-right {
  text-align: left;
}

.dots {
  z-index: 3;
  height: 13px;
  width: 13px;
  padding: 0;
  display: inline-block;
  border-radius: 100%;
  color: #FFF;
  background: #ffffff;
  border: 1px solid #000000;
}

.dots-red {
  z-index: 3;
  height: 13px;
  width: 13px;
  padding: 0;
  display: inline-block;
  border-radius: 100%;
  color: #FFF;
  background: #ff0000;
  border: 1px solid ff0000;
}

#arrow-left,
#arrow-right,
.dots {
  cursor: pointer;
  color: #F00;
}
<div id="slideshow_container">
  <img class="mySlides" src="https://appraw.com/static/previews/downloads/d/z/k/p-desert-zK6WoOEYks-1.jpg">
  <img class="mySlides" src="https://www.stockvault.net/data/2007/03/01/102413/preview16.jpg">
  <img class="mySlides" src="https://image.shutterstock.com/image-photo/da-lat-vietnam-sun-rise-600w-440121226.jpg">

  <table id="slideshow_nav" width="800" border="0" cellspacing="0" cellpadding="0">
    <tr>
      <td valign="middle" width="40px">
        <div id="arrow-left" onclick="plusDivs(-1) ">&#10094;</div>
      </td>
      <td align="center" valign="bottom">
        <span class="dots" id="dot1" onclick="currentDiv(0) "></span>
        <span class="dots" id="dot2" onclick="currentDiv(1) "></span>
        <span class="dots" id="dot3" onclick="currentDiv(2) "></span>
      </td>
      <td valign="middle" width="40px">
        <div id="arrow-right" onclick="plusDivs(1) ">&#10095;</div>
      </td>
    </tr>
  </table>
Brother58697
  • 2,290
  • 2
  • 4
  • 12
  • 1
    Wow, absolutely amazing. It was that simple? Thank you, JavaScript is still pretty difficult for me. The on hover pause JavaScript feature isn't working either, any idea what I did wrong? – Adam Tourgeman Aug 20 '22 at 15:45
  • 1
    Anytime! No worries, I'm sure every single person who made an image carrousel went through the same thing with resetting the timer. For the pause on hover, keep thinking with the same logic of the answer. Consider how the next `showDiv()` is called, and how you can stop that. If you get stuck, [here's](https://jsfiddle.net/skv7n5g0/) how you can do it. – Brother58697 Aug 20 '22 at 17:13
  • 1
    Okay so I see how you got it to work, but when hovering over and then hovering off of the image it automatically skips to the next image instead of waiting the remainder of the time. Also, the right and left arrows don't work correctly. Sorry about this. I see the mistakes once they are shown to me. I have looked for this answer and it seems like a common question, but I can't see any actual solutions that fixed it. I do not need you to give me the code, your hint is greatly appreciated. – Adam Tourgeman Aug 20 '22 at 17:58
  • 1
    No worries, here are some tips that can help you out. First, try to avoid changing `myIndex` from within `showDiv()`. Separate the roles. `showDiv()` only cares about showing the right pic and dot. Try moving the rest of the index logic and timeout in `plusDivs()` so that you're calling `plusDivs()` each time. Then trace how the function parameters are being used, and how you need to set them when they're being called. Add some `console.log`s around the code to track how everything is being being set. `console.log(myIndex)` in `plusDivs()` would be really useful. – Brother58697 Aug 20 '22 at 18:13
  • 1
    Thank you so much. I appreciate your help. I'll start giving it a try. – Adam Tourgeman Aug 20 '22 at 18:54
  • Anytime, you got this :) – Brother58697 Aug 20 '22 at 19:31