Reported problem in the Javascript of my website - javascript

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

Related

How do i add an autoplay to slider?

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>

How to change slides every 5 seconds of this JS slider?

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/

Convert inline javascript to external file

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);

Editing a Slider from w3school

So I'm trying to learn JavaScript but in the mean time I'm manipulating other's code, such as w3school's. I thought I could manage this but am struggling.
I'm trying to remove anything to do with the dot, numbering and caption from this script. I can work through process of elimination but I'd rather not end up with some messy script.
This is a link to the complete code https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto
Thank you in advance..
<script>
var slideIndex = 0;
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++) {
}
slides[slideIndex-1].style.display = "block";
setTimeout(showSlides, 4000); // Change image every 2 seconds
}
</script>
Its not that hard :)
Here you have it:
<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_fjords_wide.jpg" style="width:100%">
</div>
<div class="mySlides fade">
<img src="img_mountains_wide.jpg" style="width:100%">
</div>
</div>
<br>
<script>
var slideIndex = 0;
showSlides();
function showSlides() {
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(showSlides, 2000); // Change image every 2 seconds
}
</script>
Furthermore you might want to remove the unnecesary css classes.

getElementsByClassName returning undefined

I'm new to JavaScript. I know there are several posts on this topic, but I couldn't find one that seemed to quite address my problem.
I would like to change properties on elements with classes mainSlides and dot. But when I try to call those elements using getElementsByClassName, it returns undefined.
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mainSlides");
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";
When I inserted a breakpoint at var dots = document ... slides is undefined. Then I get an error at slides[slideIndex-1].style.display = "block";
Cannot read property 'style' of undefined
The HTML looks like this:
<div class="mainSlides fade">
<div class="numbertext">1 / 3</div>
<img src="images/mainSlide1.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
and
<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>
I'm not sure if my problem is in setting classes or using getElementsByClassName.
Your code has some logic problems:
If n > slides.length and n >= 1, then slideIndex = 1
If slides.length >= 1
OK, then you can use slides[slideIndex-1]
If slides.length === 0
Problem, slides[slideIndex-1] is undefined
If 1 <= n <= slides.length, then slideIndex is not set
slides[slideIndex-1] is probably a problem.
If n < 1, then slideIndex = slides.length
If slides.length >= 1
OK, then you can use slides[slideIndex-1]
If slides.length === 0
Problem, slides[slideIndex-1] is undefined

Categories