I'm trying to make a photo slide show. I'm trying to set a timer to run every 5 seconds with setInterval()
, I'm practicing classes and don't know how would I incorporate it within the class.
const list = document.querySelector('.js-gallery');
const items = document.querySelectorAll('.gallery__item');
Array.from(list);
class Gallery {
constructor(slideshow) {
this.slideshow = slideshow;
this.slideCount = list.length;
this.items = items[0].getBoundingClientRect().width;
this.currentSlide = 1;
}
transitionSlide() {
if (this.currentSlide < this.slideCount) {
list.style.transform = `translateX(-${this.currentSlide * this.items}px)`;
this.currentSlide = 1;
} else {
list.style.transform = `translateX(0)`;
this.currentSlide = 1;
}
}
// Trying to make a method with setInterval() so that the slide runs every 5 seconds.
}
const pics = new Gallery(list);
.title {
width: 100%;
text-align: center;
}
.gallery {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
padding: 0;
transition: all 500ms ease;
}
.gallery-container {
overflow: hidden;
position: relative;
width: 1000px;
margin: 0 auto;
}
.gallery__item {
list-style: none;
height: 500px;
min-width: 1000px;
background-position: center center;
background-size: cover;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1 >Gallery of Real Cool JS3 Images</h1>
<div >
<ul >
<li style="background-image: url('https://picsum.photos/1000/650/?image=1062')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=837')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=1025')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=237')"></li>
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
CodePudding user response:
Here's a working snippet below. I've made it so that it transitions every 0.5 seconds just so that you can see it faster. If you want it at 5 seconds, change the interval to 5000 instead of 500.
In general, setInterval doesn't work any differently in a class than outside it. You just have to be mindful of this
binding (i.e. if you did setInterval(this.transitionSlide, 5000)
, this wouldn't work as this
would lose scope, hence the .bind(this)
)
Key things to note:
You want to track the setInterval's return value, which is an interval ID. This will let you stop the interval from constantly happening.
We now have 2 functions - startSlideshow and stopSlideshow and when you instantiate a new
Gallery
, you should use.startSlideshow()
on the instance variable whenever you want it to start.You were using
list.length
for the slideCount when you needed to useitems.length
since that's what was tracking the individual slides.
const list = document.querySelector('.js-gallery');
const items = document.querySelectorAll('.gallery__item'); // Use this for slide count, not list
Array.from(list); // Doesn't do anything
class Gallery {
constructor(slideshow) {
this.slideshow = slideshow;
this.slideCount = items.length;
this.items = items[0].getBoundingClientRect().width;
this.currentSlide = 1;
this.slideTransitionInterval = null;
}
transitionSlide() {
console.log('invoked');
if (this.currentSlide < this.slideCount) {
list.style.transform = `translateX(-${this.currentSlide * this.items}px)`;
this.currentSlide = 1;
} else {
this.stopSlideshow();
list.style.transform = `translateX(0)`;
this.currentSlide = 1;
}
}
// Trying to make a method with setInterval() so that the slide runs every 5 seconds.
startSlideshow() {
this.stopSlideshow();
this.slideTransitionInterval = setInterval(this.transitionSlide.bind(this), 500);
}
stopSlideshow() {
if (this.slideTransitionInterval) {
clearInterval(this.slideTransitionInterval);
}
}
}
const pics = new Gallery(list);
pics.startSlideshow();
.title {
width: 100%;
text-align: center;
}
.gallery {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
padding: 0;
transition: all 500ms ease;
}
.gallery-container {
overflow: hidden;
position: relative;
width: 1000px;
margin: 0 auto;
}
.gallery__item {
list-style: none;
height: 500px;
min-width: 1000px;
background-position: center center;
background-size: cover;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h1 >Gallery of Real Cool JS3 Images</h1>
<div >
<ul >
<li style="background-image: url('https://picsum.photos/1000/650/?image=1062')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=837')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=1025')"></li>
<li style="background-image: url('https://picsum.photos/1000/650/?image=237')"></li>
</ul>
</div>
<script src="script.js" defer></script>
</body>
</html>
CodePudding user response:
Try something like this:
class MyClass {
constructor() {
this.startInterval(); // start interval in your constructor
}
startInterval() {
const myInterval = setInterval(this.transitionSlide, 5000);
}
transitionSlide() {
// ... logic for slideshow
console.log("Slideshow transitioned.");
}
}
const cls = new MyClass();