I know it has something to do with setInterval, but I can't seem to figure it out. I don't know a lot about JS, and I found this slider code on the internet :) I'm still struggling with JS a lot.
HTML:
<article class="slideshow-container">
<div class="mySlides">
<div class="quote-container">
<h5 class="quote-titel">Titel text</h5>
<p>Quote text</p>
</div>
</div>
<div class="mySlides">
<div class="quote-container">
<h5 class="quote-titel">Titel text</h5>
<p>Quote text</p>
</div>
</div>
</article>
<article class="dot-container">
<div class="nav-container">
<a class="prev" onclick="plusSlides(-1)"><img src="./img/svg/arrow-left.svg"></a></div>
<div class="dots">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
</div>
<div class="nav-container">
<a class="next" onclick="plusSlides(1)"><img src="./img/svg/arrow-right.svg"></a>
</div>
</article>
JS:
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";
}
Thanks in advance!
You almost there,
changeSlideInterval = setInterval(()=>plusSlides(1),5000)
//when you dont need it do not forget to destroy it
clearInterval(changeSlideInterval)
Here is a working example: https://jsfiddle.net/er28zt71/6/
Addition to that,
It was too hard to understand the problem here because you did not share a wroking code, for this kind of questions you could use https://jsfiddle.net/ (I have to google your code and find it was an example of w3schools)
Even setInterval is beautiful, if you forget to destroy them they gladly consume your resources, so check out how setInterval and setTimeout works and how you should use them https://javascript.info/settimeout-setinterval
I have used the arrow function above. when you are passing functions as parameters you should know how normal functions and arrow functions make difference. so check out them and how context works in javascript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Use setInterval this way to traverse over your elements.
On clicking Prev/Next make sure you cancel out the auto-sliding by using clearInterval
const interval = setInterval(() => {
if (userInterrupt) {
clearInterval(interval);
return;
}
plusSlides(1);
}, 5000);
Complete example: https://jsfiddle.net/3ou6kn4q/1/
Related
My website has a simple slide carousel which works correctly, but the SEOptimer evaluation report says:
“Cannot read property 'className' of undefined at showSlides (http://www.abacus-arts.org.uk/:78:8) ”
Line 78 is near the end below and says: dots[slideIndex-1].className += " active";
Can I safely ignore the SEOptimer problem report, or can you help me to fix it?
<div>
<!-- code for slides 1 to 4 removed, below are slides 5 and 6 in the carousell -->
<div class="mySlides">
<div class="picnumber"> 5 / 6</div> <img src="Pic-5-DM.jpg" alt="Pic5" style="width:100%";>
<div class="pictitle"> Breakout room LHS view </div> </div>
<div class="mySlides">
<div class="picnumber"> 6 / 6</div> <img src="Pic-6-GW.jpg" alt="Pic6" style="width:100%";>
<div class="pictitle"> Street view of entrance </div> </div>
<!-- Back and forward buttons jump to the Java Script lower down -->
<a class="prev" onclick="plusSlides(-1)"> <</a>
<a class="next" onclick="plusSlides(1)"> ></a>
</div>
<!-- from https://www.w3schools.com/howto/howto_js_slideshow_gallery.asp -->
<script>
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("demo");
// var captionText = document.getElementById("caption");
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";
// captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>
UPDATE. Solved by removing the lines for unused variables as shown //.
#phuzi Thank you all for encouraging me to search for unused variables, I found in evolving the HTML I has stopped using "demo, dots and captiontext" and the problem went away when these code lines were excluded.
Many thanks. Graeme.
var dots = document.getElementsByClassName("demo");
there is null, it mean - i dont find any classes with name "demo"
check html part code
Hi to everyone I found a slider in w3schools.com and I already implement it; You can see it here. The w3schools tutorial has the script to add the autoplay but in this case, is one or another script. ¿Is there a way to use it with arrows and autoplay?
This is the only arrows script:
<script>
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";
}
</script>
THANKS
You can do this with the code below. I have added a stop button so you can see how to stop the autoplaying as well.
N.B. I've added an id to your next button so there's no confusion about which element to click. Using class names isn't advisable if you might want to use .next elsewhere.
The code is fully commented.
Let me know if you wanted anything else.
// Start autoplaying automatically
var autoplayInterval = setInterval(function() {
// Get element via id and click next
document.getElementById("next").click();
}, 1000); // Do this every 1 second, increase this!
// Stop function added to button
function stopAutoplay() {
// Stop the autoplay
clearInterval(autoplayInterval);
}
var slideIndex = 1;
showSlides(slideIndex);
// Start autoplaying automatically
var autoplayInterval = setInterval(function() {
// Get element via id and click next
document.getElementById("next").click();
}, 1000); // Do this every 1 second, increase this!
// Stop function added to button
function stopAutoplay() {
// Stop the autoplay
clearInterval(autoplayInterval);
}
// 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";
}
<body data-new-gr-c-s-check-loaded="14.991.0" data-gr-ext-installed="">
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade" style="display: block;">
<div class="numbertext">1 / 3</div>
<img src="https://acrip.co/wp-content/uploads/2021/01/banner-panel-enero-19.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade" style="display: none;">
<div class="numbertext">2 / 3</div>
<img src="https://acrip.co/wp-content/uploads/2021/01/banner-webinar-soluciones-20-3.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade" style="display: none;">
<div class="numbertext">3 / 3</div>
<img src="https://acrip.co/wp-content/uploads/2020/12/slider_3-kactus.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a id="next" class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot active" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
<br>
<button id="stopAutoplayButton" onclick="stopAutoplay();">Stop</button>
</body>
I am working on a carousel in w3school. They actually have an inline javascript code and I am trying to convert it to an external javascript file. I have this code in my external file
window.addEventListener('DOMContentLoaded', function () {
var slideIndex = 1;
showSlides(slideIndex);
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";
}
}, false);
But when I navigate the carousel, it displays error Uncaught ReferenceError: currentSlide is not defined at HTMLSpanElement.onclick and does not work/navigate the images in the carousel
This is the HTML code
<div class="slideshow">
<div class="slideshow-container">
<div class="mySlides fade">
<img class="carousel-item" src="https://lorempixel.com/800/400/food/1">
</div>
<div class="mySlides fade">
<img class="carousel-item" src="https://lorempixel.com/800/400/food/2">
</div>
</div>
<div class="slide-nav">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
</div>
</div>
<script type="text/javascript" src="js/components.js"></script>
Because currentSlide is not globally accessible (HTML inline event handlers run in the global scope). You need to define it in the global scope for it to work:
function currentSlide(n) {
showSlides(slideIndex = n);
}
window.addEventListener("DOMContentLoaded", function() {...}, false);
I am looking to create multiple slideshows on a single page however it is currently not working
I understand that this question has been asked before but I can't seem to make those answers work with my code, does anyone have any suggestions? I don't have a huge amount of experience with Javascript
<div class="bareEditorial">
<div class="slideshow-container" onclick="plusSlides(1)">
<div class="mySlides fade">
<div class="image">
<img src="bareEditorialHero.jpg">
</div>
</div>
<div class="mySlides fade">
<div class="image">
<img src="bareEditorial2.jpg">
</div>
</div>
<div class="mySlides fade">
<div class="image">
<img src="bareEditorial3.jpg">
</div>
</div>
<div class="ninetydegrees">
<div class="nextprevious">
<div class="numbertext">Bare Boutique Editorial 2018 (<span>1</span> / <span>6</span>)</div>
</div>
var slideIndex = 1;
var indexes = document.querySelectorAll(".numbertext span");
var slides = document.getElementsByClassName("mySlides");
indexes[1].innerHTML = slides.length;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
indexes[0].innerHTML = slideIndex;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
$(function() {
$('body').removeClass('fade-out');
});
Considering that you need information on implementing multiple slideshows on a page and not going into the detailed working for each, I'll suggest you to have a slideshow container with unique id for each slideshow and call your initialization method on each by passing the id as an argument.
Create a method as initializeSlideshow(containerID) and in that bind methods to for example next button as
function initializeSlideshow(containerID) {
$('#' + containerID + '.prevLink').on('click', function() {} );
//rest of your logic
}
Another approach would be to add a class to each container and implement the methods in a way that you capture the respective container using closest() and manipulate DOM
$('.containerClass .prevLink').on('click', function() {
$(this).closest('.containerClass').find('.slideCLass');
});
In an ideal scenario, one should write code to implement slideshow logic as a plugin where you can simply do
$('.slideshowContainer').initializeSlideshow( {
//slideshow options.
})
Which can be implemented as
$.fn.initializeSlideshow = function(slideshowOptions) {
//your logic where reference to this (object on which the method is called) is available
}
I am trying to create a image slideshow. Presently I write a simple code to display images. Now when I add new images to the same folder I have to again update the code for displaying the new image. How do I make it dynamic so that the code automatically picks the image and displays in the HTML page.
<body>
<div class="slideshow-container">
<div class="mySlides fade">
<img src="img_nature_wide.jpg" style="width:100%">
</div>
<div class="mySlides fade">
<img src="img_snow_wide.jpg" style="width:100%">
</div>
<div class="mySlides fade">
<img src="img_mountains_wide.jpg" style="width:100%">
</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>
<script>
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";
}
</script>
</body>
Optionally, if you are not using server side scripting, you can use a JavaScript array and insert images. Will not work for 50 images, it's cumbersome.
document.addEventListener( 'DOMContentLoaded', function(){
// insert your images here
var imgs = [ 'one.jpg', 'two.jpg' ];
var div, img;
for( var x = 0; x < imgs.length;x++ ){
div = document.createElement('div');
div.className = 'mylides fade';
img = document.createElement('img');
img.src = imgs[x];
div.appendChild( img );
document.querySelector('.slideshow-container').insertBerofe( div, document.querySelector('.next') );
}
}, false
)