I'm struggling with debugging this slideshow. I have understood everything except this part:
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';
This is the last part of the javascript code. Please, can anyone explain this to me line by line. I have tried to use the debugger and I didn't understand how does it work.
Here is the whole code:
HTML:
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="img1.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="img2.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="img3.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
CSS:
* { box-sizing:border-box }
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* 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);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
JavaScript:
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides((slideIndex += n));
}
// Thumbnail image controls
function currentSlide(n) {
showSlides((slideIndex = n));
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName('mySlides');
var dots = document.getElementsByClassName('dot');
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';
}
By the way, I have found this on w3schools.com I'm struggling with the last part as I said I don't know:
Why they replace "active" with ""?
Why they used this += sign what does it do in this case?
please try to make it simple as simple as possible and thaaaaank youuuuu in advance :)
The first for loop hides all of the slides, by setting the CSS display property to "none". The second 'for' loop makes the "current" slide button look inactive.
The second to last line of code makes the previous slide (slides[slideIndex-1]) visible. The last line makes the button for the previous slide look active.
Related
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
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";
}
* {
box-sizing: border-box
}
#media(max-width:768px) {
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
.mySlides {
display: none;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: #717171;
}
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
}
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<img class="main-description-img1 " src="images/main-colin.png" alt="">
</div>
<div class="mySlides fade">
< <img class="main-description-img2" src="images/main-marching.png" alt="">
</div>
<div class="mySlides fade">
<img class="main-description-img3" src="images/main-president.png" alt="">
<a href="#">
</div>
<div class="mySlides fade">
< <img class="main-description-img2" src="images/main-working.png" alt="">
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
<span class="dot" onclick="currentSlide(4)"></span>
</div>
Hello. How can i bind Javascript code to a media query in CSS so that it works only when the screen reaches a given width. At the beginning, all the blocks are arranged in a row. after shrinking the screen to 768px, I want the blocks to turn into a slide. how it can be implemented. I tried to add if (windows.innerWidth <= 768) {} to the code, so when this size is reached, the slides disappear altogether. Without a copper request in css and adding conditions to JS, everything works and shows as a slide.
If you want a media query like solution for javascript you have to listen for the resize event with an event listener and call the slide function showSlides() in it. In the slide function you have to wrap the code in the if statement that asks for window.innerWidth. Additionally you have to define an else block for showing the images again.
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
if (window.innerWidth <= 768) {
... //your original code of that function except the first two vars
}
else {
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "inline-block";
}
}
}
window.addEventListener('resize', function() {
showSlides(slideIndex);
});
Working example (i changed display: block to inline-block for aligning the images in a row):
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
if (window.innerWidth <= 768) {
var dots = document.getElementsByClassName("dot");
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 = "inline-block";
dots[slideIndex - 1].className += " active";
}
else {
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "inline-block";
}
}
}
window.addEventListener('resize', function() {
showSlides(slideIndex);
});
* {
box-sizing: border-box
}
#media(max-width:768px) {
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
.mySlides {
display: none;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: #717171;
}
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
}
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<img class="main-description-img1 " src="https://loremflickr.com/160/120?random=1" alt="">
</div>
<div class="mySlides fade">
<img class="main-description-img2" src="https://loremflickr.com/160/120?random=2" alt="">
</div>
<div class="mySlides fade">
<img class="main-description-img3" src="https://loremflickr.com/160/120?random=3" alt="">
</div>
<div class="mySlides fade">
<img class="main-description-img2" src="https://loremflickr.com/160/120?random=4" alt="">
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
<span class="dot" onclick="currentSlide(4)"></span>
</div>
Essentially, my website's next arrow for the slideshow is working, but when you click on it, the image moves on and the timer still continues instead of stopping. If you keep clicking the next button, it skips the second image and then after stopping, it continues on very quickly in switching images. It is a peculiar bug and here it is in action: https://codepen.io/kush2610/pen/bGNYBPe
HTML CODE
<section class="pictures">
<h2 >Product Portfolio</h2 >
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1508138221679-760a23a2285b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1567&q=80" style="width:100%">
</div>
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3900&q=80" style="width:100%">
</div>
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1485550409059-9afb054cada4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2598&q=80" style="width:100%">
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
</section>
Sorry if this sounds really strange what I am describing but it is such a strange bug I honestly do not know what else to say.
Don't use the same name for both showSlides functions. Overloading functions is not an option in JavaScript.
/* The SlideShow */
var slideIndex = 0;
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
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";
}
function showNextSlide() {
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(showNextSlide, 7000); // Change image every 7 seconds
}
showNextSlide();
.pictures {
padding-top: 50px;
padding-right: 30px;
padding-bottom: 50px;
padding-left: 80px;
;
}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* 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);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
<!--Slideshow of the area
================================================== -->
<section class="pictures">
<h2>Product Portfolio</h2>
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1508138221679-760a23a2285b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1567&q=80" style="width:100%">
</div>
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3900&q=80" style="width:100%">
</div>
<div class="mySlides fade">
<img src="https://images.unsplash.com/photo-1485550409059-9afb054cada4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2598&q=80" style="width:100%">
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
</section>
It looks like your showSlides() function is setting a timeout which advances the slides. When you click your next button, another function is called, plusSlides(), which in turn calls showSlides() again. Thus, starting another timeout. The more you click the next button, the more timeouts you'll have running, and the more frequently you'll see your slides advance.
I don't have time to write the code right now, but I'd suggest killing any existing timeouts when you click the next button so you only have one running at a time.
This question already has answers here:
Making a slideshow with arrays Javascript
(3 answers)
Closed 3 years ago.
I'm trying to finish my first website, I have short deadline, I know html css and a bit of JQuery, but right JS is still difficult for me
I would like to have a slideshow in my website, that's why I went to the w3school and tried to replicate the example in my visual studio code.
$(document).ready(() => {
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("myslides");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
});
.slideshow-container {
max-width: 100%;
position: relative;
margin: auto;
}
.myslides {
display: none;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.fade {
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slideshow-container">
<div class="myslides fade">
<img src="./IMAGENS/CASA A (1).jpg" width="100%">
</div>
<div class="myslides fade">
<img src="./IMAGENS/CASA B (3).jpg" width="100%">
</div>
<div class="myslides fade">
<img src="./IMAGENS/MUDA_L11_02_FINAL.jpg" width="100%">
</div>
<div class="myslides fade">
<img src="./IMAGENS/MUDA_L11_05_FINAL.jpg" width="100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
When I try to refresh the page everything looks fine but when I click in the button to change slides nothing happens. What you think should I do?
I tried to make a slideshow with arrays and it didn´t work. So I think it´s a problem with my VSCODE not assuming these two elements.
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
In my program when I do onclick="plusSlides(-1)" the first quote appears in yellow but the second one in white it seems that onclick is not asssigned
Just as #edinhajdarevic said, using an array is a better approach due to many advantages, some of those are the following:
Rendering your slides in the DOM using an array makes your structure dynamic. Dynamic means, everytime you want to add a new slide, you could append a new slide object to your array of slides, instead of writting an HTML and a JavaScript every slide by hand.
Once you have all of your slide code defined, you will be able to mantain your code with ease, instead of reading multiple lines, you just have to care about your JavaScript code.
Less error prone, every time you copy/paste HTML or JavaScript to build another slide, you will have to change values based on the new slide, sometimes this turns into a messy work causing bugs in a future.
A nice tutorial can be found in the following W3Schools link:
Slideshow Tutorial
Your functions are declared on scope of $(document).ready's callback, so onclick cannot reach them.
Solution 1: Move your declarations outside $(document).ready's callback.
var slideIndex = 1;
$(document).ready(() => {
showSlides(slideIndex);
});
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("myslides");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
.slideshow-container {
max-width: 100%;
position: relative;
margin: auto;
}
.myslides {
display: none;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.fade {
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slideshow-container">
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+1" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+2" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+3" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+4" width="100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
Solution 2: Remove onclick attributes and add click listeners in $(document).ready's callback
$(document).ready(() => {
var slideIndex = 1;
showSlides(slideIndex);
$(".prev").click(function() {
plusSlides(-1);
});
$(".next").click(function() {
plusSlides(1);
});
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("myslides");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
});
.slideshow-container {
max-width: 100%;
position: relative;
margin: auto;
}
.myslides {
display: none;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.fade {
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slideshow-container">
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+1" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+2" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+3" width="100%">
</div>
<div class="myslides fade">
<img src="https://via.placeholder.com/400x200&text=image+4" width="100%">
</div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
I am creating slideshow code by mixing two codes of w3school example, all other things like next button are working fine. Only previous button (for loading previous image) is not working. I am debugging the JavaScript but not able to find or rectify the bug.
SlideShow ScreenShot
/slideshow.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="slideshow_style.css">
</head>
<body>
<!-- Slideshow container -->
<div class="slideshow-container" onmouseover="stop_timeout()" onmouseout="start_timeout()">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<div class="numbertext">1 / 4</div>
<img src="img_lights_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 4</div>
<img src="img_mountains_wide.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 4</div>
<img src="img_snow_wide.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<div class="mySlides fade">
<div class="numbertext">4 / 4</div>
<img src="img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Four</div>
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<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>
<script src="slideshow_script.js"></script>
</body>
</html>
/slideshow_script.js
var slideIndex = 0;
showSlides(slideIndex);
function plusSlides(n) {
clearTimeout(myTime);
if(n===1){showSlides(slideIndex += (n-1));}
if(n===-1){showSlides(slideIndex += n);}
clearTimeout(myTime);
}
function currentSlide(n) {
clearTimeout(myTime);
showSlides(slideIndex = n);
}
function showSlides(num) {
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}
if (num > slides.length) {slideIndex = 0}
if (num < 1) {slideIndex = slides.length - 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";
myTime = setTimeout(showSlides, 3000); // Change image every 3 seconds
}
function start_timeout() {
myTime = setTimeout(showSlides, 3000); // Change image every 3 seconds
}
function stop_timeout() {
clearTimeout(myTime);
}
/slideshow_style.css
* {box-sizing:border-box}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
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;
}
/* 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);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
I know this is stupid question, but i am stuck. Please help me out, how can i make this code working. Please point out the bug. Thanks in advance.
Try replacing the line
if(n===-1){showSlides(slideIndex += n);}
with
if(n===-1){showSlides(slideIndex += (n-1));}
Also, just before the two lines
if (num > slides.length) {slideIndex = 0}
if (num < 1) {slideIndex = slides.length - 1}
add the following line:
if (slideIndex < 1) {slideIndex = slides.length; }
Also delete or comment out the two lines beginning if (num ...).
To be honest, there are aspects of your code that are confusing and are not helping you. It seems to me as if you haven't fully understood the code you have written and have just put things in because they seem to make it work.
Once you've got your code working, there's plenty of scope for writing it better. Take a look at https://codereview.stackexchange.com/.
I would like to know how to make this slider to automatic slideshow.
This slider contains clickable bullets at the bottom and pre/next buttons on the slides but doesn't animate itself.
Would anyone please let me know how to make it automatic slideshow?
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow
Thank you in advance.
Use setInterval() function to make the slideshow automatically for the certain time interval.
Add the setInterval() function in your example reference link after the below line:
var slideIndex = 1;
showSlides(slideIndex);
setInterval(function(){ showSlides(++slideIndex); }, 1000);
The slide will be changed every 1000 milli seconds. If you need you can adjust the time as per your need.
You could do what the click on the next button does: call plusSlider with a parameter 1.
To do that every 2000ms your can use setInterval. On that w3schools tryit page put following code before the closing </script> then run it:
setInterval(plusSlides,2000,1);
What I would recommend is making use of a setInterval() function such as the following:
setInterval(function() {
slideIndex++;
showSlides(slideIndex);
}, 3000);
The above function increases the current index, then triggers the showSlides() function, passing the index as a parameter. The 3000 denotes the speed at which the automation should occur, with the time specified in millseconds. Note that setInterval() should be used rather than setTimeout(), because setInteravl() fires more than once.
This gives the following result:
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
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";
}
setInterval(function() {
slideIndex++;
showSlides(slideIndex);
}, 3000);
* {
box-sizing: border-box
}
body {
font-family: Verdana, sans-serif;
margin: 0
}
.mySlides {
display: none
}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
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;
}
/* 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);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 13px;
width: 13px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
/* On smaller screens, decrease text size */
#media only screen and (max-width: 300px) {
.prev,
.next,
.text {
font-size: 11px
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="https://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
</body>
</html>
Hope this helps! :)