简体   繁体   中英

When clicking on the navigation or the indicators the slideshow speeds up

In the following code when I click on the navigation or the indicators the slideshow speeds up. How do I get the controls to work correctly but keep the same timing?

When clicking on the left arrow the slide should go back one slide. When clicking on the right arrow the slide should go forward on slide. When clicking on the indicators (1,2,3,4) that slide should bee selected. Then resume the current timing.

  var slideIndex = 0; showSlides(slideIndex); function plusSlides(n) { showSlides(slideIndex += n); } function currentSlide(n) { showSlides(slideIndex = n); } function showSlides() { var i; var slides = document.getElementsByClassName("mySlides"); var dots = document.getElementsByClassName("dot"); for (i = 0; i < slides.length; i++) { slides[i].style.display = "none"; } slideIndex++; if (slideIndex > slides.length) {slideIndex = 1;} for (i = 0; i < dots.length; i++) { dots[i].className = dots[i].className.replace(" active", ""); } slides[slideIndex-1].style.display = "block"; dots[slideIndex-1].className += " active"; setTimeout(showSlides, 10000); // 1000 = 1 sec } 
 /* Slideshow container */ .slideshow-container { width: 600px; position: relative; margin: auto; /*top: 50px;*/ height: 600px; } .mySlides { width: auto; } /* The dots/bullets/indicators */ .dot { height: 13px; width: 13px; margin: 0 2px; background-color: lightgray; border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; } .active, .dot:hover { background-color: #717171; } /* Next & previous buttons */ .prev, .next { cursor: pointer; position: absolute; top: 20px; width: auto; padding: 6px; color: black; font-weight: bold; font-size: 18px; transition: 0.6s ease; border-radius: 0 3px 3px 0; } /* Position the "next button" to the right */ .next { right: 0; border-radius: 3px 0 0 3px; } .prev:hover, .next:hover { background-color: black; color: white; } 
 <div class="slideshow-container"> <a class="prev" onclick="plusSlides(-2)">&#10094;</a> <div style="text-align:center; padding-top: 30px;"> <span class="dot" onclick="currentSlide(0)"></span> <span class="dot" onclick="currentSlide(1)"></span> <span class="dot" onclick="currentSlide(2)"></span> <span class="dot" onclick="currentSlide(3)"></span> </div> <a class="next" onclick="plusSlides(0)">&#10095;</a> <!--Slide 1--> <div class="mySlides"> <p>Image 1</p> <img src="//dummyimage.com/600"> </div> <!--Slide 2--> <div class="mySlides"> <p>Image 2</p> <img src="//dummyimage.com/600"> </div> <!--Slide 3--> <div class="mySlides"> <p>Image 3</p> <img src="//dummyimage.com/600"> </div> <!--Silde 4--> <div class="mySlides"> <p>Image 4</p> <img src="//dummyimage.com/600"> </div> </div> 

First of all, you don't need input parameter to showSlides function.

The problem you are having is your function recursively trigger setTimeout(showSlides, 10000); when the user click the navigator or arrows.

The following code reset the timer by clear current setTimeout task.

  var slideIndex = 0; var currentTask = null; showSlides(); function plusSlides(n) { slideIndex += n; showSlides(); } function currentSlide(n) { slideIndex = n; showSlides(); } function showSlides() { var i; var slides = document.getElementsByClassName("mySlides"); var dots = document.getElementsByClassName("dot"); for (i = 0; i < slides.length; i++) { slides[i].style.display = "none"; } slideIndex++; if (slideIndex > slides.length) {slideIndex = 1;} for (i = 0; i < dots.length; i++) { dots[i].className = dots[i].className.replace(" active", ""); } slides[slideIndex-1].style.display = "block"; dots[slideIndex-1].className += " active"; if (currentTask) { clearTimeout(currentTask); currentTask = null; } currentTask = setTimeout(showSlides, 10000); // 1000 = 1 sec } 
 /* Slideshow container */ .slideshow-container { width: 600px; position: relative; margin: auto; /*top: 50px;*/ height: 600px; } .mySlides { width: auto; } /* The dots/bullets/indicators */ .dot { height: 13px; width: 13px; margin: 0 2px; background-color: lightgray; border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; } .active, .dot:hover { background-color: #717171; } /* Next & previous buttons */ .prev, .next { cursor: pointer; position: absolute; top: 20px; width: auto; padding: 6px; color: black; font-weight: bold; font-size: 18px; transition: 0.6s ease; border-radius: 0 3px 3px 0; } /* Position the "next button" to the right */ .next { right: 0; border-radius: 3px 0 0 3px; } .prev:hover, .next:hover { background-color: black; color: white; } 
 <div class="slideshow-container"> <a class="prev" onclick="plusSlides(-2)">&#10094;</a> <div style="text-align:center; padding-top: 30px;"> <span class="dot" onclick="currentSlide(0)"></span> <span class="dot" onclick="currentSlide(1)"></span> <span class="dot" onclick="currentSlide(2)"></span> <span class="dot" onclick="currentSlide(3)"></span> </div> <a class="next" onclick="plusSlides(0)">&#10095;</a> <!--Slide 1--> <div class="mySlides"> <p>Image 1</p> <img src="//dummyimage.com/600"> </div> <!--Slide 2--> <div class="mySlides"> <p>Image 2</p> <img src="//dummyimage.com/600"> </div> <!--Slide 3--> <div class="mySlides"> <p>Image 3</p> <img src="//dummyimage.com/600"> </div> <!--Silde 4--> <div class="mySlides"> <p>Image 4</p> <img src="//dummyimage.com/600"> </div> </div> 

You had a couple of errors in your approach. The below is a solution based on the setInterval function:

  var slideIndex = 1; var millis = 2000; nextSlide(); var interval = setInterval(nextSlide, millis); function nextSlide() { showSlide(); slideIndex++; } function plusSlides(n) { clearInterval(interval); slideIndex += n; nextSlide(); interval = setInterval(nextSlide, millis); } function currentSlide(n) { clearInterval(interval); slideIndex = n + 1; nextSlide(); interval = setInterval(nextSlide, millis); } function showSlide() { var i; var slides = document.getElementsByClassName("mySlides"); var dots = document.getElementsByClassName("dot"); for (i = 0; i < slides.length; i++) { slides[i].style.display = "none"; } if (slideIndex > slides.length) {slideIndex = 1;} if (slideIndex < 1) {slideIndex = slides.length;} for (i = 0; i < dots.length; i++) { dots[i].className = dots[i].className.replace(" active", ""); } slides[slideIndex-1].style.display = "block"; dots[slideIndex-1].className += " active"; } 
 /* Slideshow container */ .slideshow-container { width: 600px; position: relative; margin: auto; /*top: 50px;*/ height: 600px; } .mySlides { width: auto; } /* The dots/bullets/indicators */ .dot { height: 13px; width: 13px; margin: 0 2px; background-color: lightgray; border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; } .active, .dot:hover { background-color: #717171; } /* Next & previous buttons */ .prev, .next { cursor: pointer; position: absolute; top: 20px; width: auto; padding: 6px; color: black; font-weight: bold; font-size: 18px; transition: 0.6s ease; border-radius: 0 3px 3px 0; } /* Position the "next button" to the right */ .next { right: 0; border-radius: 3px 0 0 3px; } .prev:hover, .next:hover { background-color: black; color: white; } 
 <div class="slideshow-container"> <a class="prev" onclick="plusSlides(-2)">&#10094;</a> <div style="text-align:center; padding-top: 30px;"> <span class="dot" onclick="currentSlide(0)"></span> <span class="dot" onclick="currentSlide(1)"></span> <span class="dot" onclick="currentSlide(2)"></span> <span class="dot" onclick="currentSlide(3)"></span> </div> <a class="next" onclick="plusSlides(0)">&#10095;</a> <!--Slide 1--> <div class="mySlides"> <p>Image 1</p> <img src="//dummyimage.com/600"> </div> <!--Slide 2--> <div class="mySlides"> <p>Image 2</p> <img src="//dummyimage.com/600"> </div> <!--Slide 3--> <div class="mySlides"> <p>Image 3</p> <img src="//dummyimage.com/600"> </div> <!--Silde 4--> <div class="mySlides"> <p>Image 4</p> <img src="//dummyimage.com/600"> </div> </div> 

Check out Nivo Slider .

It sounds like exactly what you want without the speed up problem. They have a demo folder in the Github Source that shows you exactly how to use it.

Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM