最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Automatic and manual slideshow - Stack Overflow

programmeradmin1浏览0评论

I have to make a slideshow that has to work both automatic and manual.

For the manual part I have two buttons: next and previous that allows me to see the photos without having to wait a certain period of time between images.

When I don't click on the buttons, the slideshow goes automatic and the images change after six seconds (for example).

My problem is that, after I click on the previous/ next button, the images start to appear faster or they appear more than one on the screen.

Here is the code I am working with:

var slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("hidden");

  if (n===undefined){n= ++slideIndex;}
  if (n > slides.length) {slideIndex = 1;}
  if (n < 1) {slideIndex = slides.length}

  $(slides[slideIndex-1]).fadeIn(2000);
  slides[slideIndex-1].style.display = "block";
  $(slides[slideIndex-1]).delay(3000);
  $(slides[slideIndex-1]).fadeOut(1000);

  setTimeout(showSlides, 6000);
}
.hidden {
  display: none;
}
<!DOCTYPE html>
<html>
<head>
  <script src=".1.1/jquery.min.js"></script>
  <meta charset="utf-8">
  <title>jQuery</title>
  <link rel="stylesheet" href="lab5.css" media="screen" title="no title">
</head>
<body>
  <h1 class="titlu">Goodies</h1>
  <div align="center">
    <button class="button" onclick="plusSlides(-1)" >Previous</button>
    <button class="button" onclick="plusSlides(1)" >Next</button>
  </div>
  <div class="hidden">
    <h4 class="num" > 1 / 5 </h4>
    <img src="">
  </div>
  <div class="hidden">
    <h4 class="num"> 2 / 5 </h4>
    <img src="">
  </div>
  <div class="hidden">
    <h4 class="num"> 3 / 5 </h4>
    <img src="">
  </div>
  <div class="hidden">
    <h4 class="num"> 4 / 5 </h4>
    <img src="">
  </div>
  <div class="hidden">
    <h4 class="num"> 5 / 5 </h4>
    <img src="">
  </div>
</body>
</html>

I have to make a slideshow that has to work both automatic and manual.

For the manual part I have two buttons: next and previous that allows me to see the photos without having to wait a certain period of time between images.

When I don't click on the buttons, the slideshow goes automatic and the images change after six seconds (for example).

My problem is that, after I click on the previous/ next button, the images start to appear faster or they appear more than one on the screen.

Here is the code I am working with:

var slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("hidden");

  if (n===undefined){n= ++slideIndex;}
  if (n > slides.length) {slideIndex = 1;}
  if (n < 1) {slideIndex = slides.length}

  $(slides[slideIndex-1]).fadeIn(2000);
  slides[slideIndex-1].style.display = "block";
  $(slides[slideIndex-1]).delay(3000);
  $(slides[slideIndex-1]).fadeOut(1000);

  setTimeout(showSlides, 6000);
}
.hidden {
  display: none;
}
<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <meta charset="utf-8">
  <title>jQuery</title>
  <link rel="stylesheet" href="lab5.css" media="screen" title="no title">
</head>
<body>
  <h1 class="titlu">Goodies</h1>
  <div align="center">
    <button class="button" onclick="plusSlides(-1)" >Previous</button>
    <button class="button" onclick="plusSlides(1)" >Next</button>
  </div>
  <div class="hidden">
    <h4 class="num" > 1 / 5 </h4>
    <img src="http://placehold.it/150x150?text=1">
  </div>
  <div class="hidden">
    <h4 class="num"> 2 / 5 </h4>
    <img src="http://placehold.it/150x150?text=2">
  </div>
  <div class="hidden">
    <h4 class="num"> 3 / 5 </h4>
    <img src="http://placehold.it/150x150?text=3">
  </div>
  <div class="hidden">
    <h4 class="num"> 4 / 5 </h4>
    <img src="http://placehold.it/150x150?text=4">
  </div>
  <div class="hidden">
    <h4 class="num"> 5 / 5 </h4>
    <img src="http://placehold.it/150x150?text=5">
  </div>
</body>
</html>

Is there a way I can make the slideshow return to its "speed" of showing the images every six seconds after I click on previous/next?

Also, how can I prevent it from showing more than one image at a time?

Share Improve this question edited Nov 16, 2016 at 19:50 user4639281 asked Nov 16, 2016 at 17:52 user7167081user7167081 391 gold badge1 silver badge8 bronze badges 3
  • Just a little remark: you can use if (!n) {...} instead of if (n===undefined) {...}. It's more short and readable. – P.S. Commented Nov 16, 2016 at 18:00
  • @CommercialSuicide, I wouldn't recommend that - especially when working with numbers or any kind of type that might have a value that is falsy (e.g., 0, ''), as !0 === true. – JanS Commented Nov 16, 2016 at 22:15
  • 2 @JanS, sure, if someone wants to use if (!n) {...} construction, he needs to know about coercion and the behavior of primitives – P.S. Commented Nov 16, 2016 at 22:19
Add a comment  | 

3 Answers 3

Reset to default 10

Here's working code for an auto and manual slideshow with the timer as suggested by Scott. It works with the html and css from this how to which the questioner based his code on. https://www.w3schools.com/howto/howto_js_slideshow.asp

var slideIndex = 1;
var timer = null;
showSlides(slideIndex);

function plusSlides(n) {
  clearTimeout(timer);
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  clearTimeout(timer);
  showSlides(slideIndex = n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  var dots = document.getElementsByClassName("dot");
  if (n==undefined){n = ++slideIndex}
  if (n > slides.length) {slideIndex = 1}
  if (n < 1) {slideIndex = slides.length}
  for (i = 0; i < slides.length; i++) {
      slides[i].style.display = "none";
  }
  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";
  timer = setTimeout(showSlides, 5000);
} 

What's happening is that you are causing multiple timers to be started, which causes your callback function to run more often than it should.

You need to make sure that you capture the integer that is returned from your timer:

var timer = null; // Do this in a scope that is accessible to all your relevant functions

...then:

timer = setTimeout(showSlides, 6000);

So that you can cancel the timer where appropriate:

clearTimeout(timer);

You will want to clear your timer upon the clicking of the button, which will stop the automatic one from running and then you can start a new one, leaving you with only one running timer.

<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<style>
.mySlides {display:none;}
</style>
<body>

<h2 class="w3-center">Manual Slideshow</h2>

<div class="w3-content w3-display-container">
  <img class="mySlides" src="img_snowtops.jpg" style="width:100%">
  <img class="mySlides" src="img_lights.jpg" style="width:100%">
  <img class="mySlides" src="img_mountains.jpg" style="width:100%">
  <img class="mySlides" src="img_forest.jpg" style="width:100%">

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

**SCRIPT CODES**
<script>
var slideIndex = 1;
showDivs(slideIndex);

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

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";  
}
</script>

</body>
</html>


**//CSS CODES**
/* Slideshow container */
.slideshow-container {
  height:500px;
  position: relative;
  margin: auto;
  with:800px;
}

/* Hide the images by default */
.mySlides {
    display: none;
}


/* Next & previous buttons */
.prev, .next {
    background-color:gold;
  cursor: pointer;
  position: absolute;
  top: 50%;
  width: auto;
  margin-top: -22px;
  padding: 20px;
  color: black;
  font-weight: bold;
  font-size: 24px;
  transition: 0.6s ease;
  border-radius: 7 7px 7px 7;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
  background-color: rgba(0,0,0,0.8);
  color:white;
}

/* Caption text */
.text {
  color:lime;
  font-size: 22px;
  padding: 8px 12px;
  position: absolute;
  bottom: 8px;
  width: 100%;
  text-align: center;
}

/* Number text (1/3 etc) */
.numbertext {
  color:lime;
  font-size: 22px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* The dots/bullets/indicators */
.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #000000;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.2s ease;
}

.active, .dot:hover {
  background-color: #ff0101;
}

/* Fading animation */
.fade {
  -webkit-animation-name: fade;
  -webkit-animation-duration: 0.2s;
  animation-name: fade;
  animation-duration: 6.5s;
}

@-webkit-keyframes fade {
  from {opacity: .4} 
  to {opacity: 1}
}

@keyframes fade {
  from {opacity: .4} 
  to {opacity: 1}
发布评论

评论列表(0)

  1. 暂无评论