Before explaining the problem, here is a little of context. School wanted us to build from scratch a One Page web resume using only HTML/CSS, Javascript and JQuery.
For that project, I had a lot of ideas. One of them was to use a quote slider. Each x seconds it slides to the next quote. So I went looking for something that would work and I found this and adapted it to make it look like :
slideIndex = 1;
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("slide");
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(" activeDot", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " activeDot";
}
$(document).ready(function() {
showSlides(slideIndex);
setInterval(() => {
plusSlides(1);
}, 5000);
});
.sliderContainer {
position: relative;
background: #eee;
/* Not useful here */
}
.slide {
display: none;
padding: 30px;
text-align: center;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -30px;
padding: 16px;
color: #444;
font-weight: bold;
font-size: 20px;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
position: absolute;
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
/* Changes color and background color */
}
.dotContainer {
margin-bottom: 30px;
text-align: center;
padding: 20px;
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 20px;
background-color: #444;
/* still not useful but I let it */
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.activeDot,
.dot:hover {
/* changes background-color */
}
q {
/* changes font-style */
}
.author {
/* changes color */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script>
<div class="sliderContainer">
<div class="slide">
<q>A quote</q>
<p class="author">The quote's author</p>
</div>
<div class="slide">
<q>Another quote</q>
<p class="author">The quote's other author</p>
</div>
<!-- Left and Right buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<div class="dotContainer">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
</div>
So, this code works perfectly fine.
But then I wanted to add another slider somewhere else. It was a figure slider and not a quote slider, but that doesn't change anything. I did build it in the HTML and looked how that work. And it didn't work correctly because all the slides had the same class. Obviously.
Then I tried changing the classes from slide to quoteSlide and figureSlide. Then I realised I needed to change all the JavaScript related to that.
Well, for only 2 sliders, it doesn't mind. I just did a copy/paste and changed the name of the functions and other small things to get the quote adapted script and the figure adapted script.
But then, I realised I would need a total of seven sliders. And I wouldn't get seven times the same script. So I thought and I found an interesting idea. In my school cursus, we learn a lot of OOP (Object Oriented Programming). But we never talked about it in Javascript class. So I said to myself, why not trying to do this.
This wasn't the simplest thing to learn, but I managed to get something. Spoiler : this thing didn't work. But here it is :
class Slider {
slideIndex = 1;
slides;
dots;
constructor(index = 1, slides, dots) {
slideIndex = index;
slides = document.getElementsByClassName(slides);
dots = document.getElementsByClassName(dots);
}
plusSlides(n) {
showSlides(slideIndex += n);
}
currentSlide(n) {
showSlides(slideIndex = n);
}
showSlides(n) {
var i;
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(" activeDot", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " activeDot";
}
setupSlider() {
showSlides(slideIndex);
// Sliding automation
setInterval(() => {
plusSlides(1);
console.log(this.slideIndex);
}, 5000);
}
}
And here is the code in the main JS file :
let quoteSlider = new Slider(1, ".quoteSlide", ".quoteDot");
let lectureSlider = new Slider(1, ".lectureSlide", ".lectureDot");
let gameSlider = new Slider(1, ".gameSlide", ".gameDot");
let softwareSlider = new Slider(1, ".softwareSlide", ".softwareDot");
let roboticSlider = new Slider(1, ".roboticSlide", ".roboticDot");
let teachingSlider = new Slider(1, ".teachingSlide", ".teachingDot");
let streamingSlider = new Slider(1, ".streamingSlide", ".streamingDot");
quoteSlider.setupSlider();
lectureSlider.setupSlider();
gameSlider.setupSlider();
softwareSlider.setupSlider();
roboticSlider.setupSlider();
teachingSlider.setupSlider();
streamingSlider.setupSlider();
This code doesn't work, but I can't understand why.
So here are my questions :
- Did I made an error in my thinking process ? Which one ?
- Where in all this JS stuff I made a mistake ?
- What would have been the solution you'd gave to the teacher knowing the context ?
- Is there something to do better globally ?
Disclaimer : This project is over. I waited on purpose for the end of the time-limit to ask as I didn't want to use other people's code to get points for this class.
Thanks for your help, and sorry for that so long text.