maybe someone can tell me, how to make it so that when clicking next, the user sees an infinite loop of slider elements? At the moment, I was only able to make the elements move inside the slider. I'm assuming that I need to create new items inside the carousel on every click.
I would be grateful for advice on what to do next.
function sliderFunc() {
let sliderBox = document.querySelector('.slider');
let tapToRightBtn = document.querySelector('.btn');
function sliderNext() {
sliderBox.style.transform = 'translateX(-100px)';
sliderBox.style.transition = '0.3s';
}
tapToRightBtn.addEventListener('click', sliderNext);
}
sliderFunc();
.container {
max-width: 300px;
margin: auto;
overflow: hidden;
}
.slider {
background: #eee;
display: flex;
width: 500px;
border: solid;
}
.slide {
width: 200px;
height: 100px;
margin-right: 10px;
}
.slide1 {
background: #f3ca63;
}
.slide2 {
background: #d06c65;
}
.slide3 {
background: #6579d0;
}
.slide4 {
background: #65d073;
}
.slide5 {
background: #ba65d0;
}
.btn {
margin: 2rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<section >
<div >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</div>
<button >Next</button>
</section>
</body>
</html>
CodePudding user response:
I made a simple script based on what you want. You may want to optimize it by removing the object(s) when they are not displayed.
What I have changed:
- Instead of transitioning using
translateX(-100px)
, I make the container positionrelative
then moving usingleft
attribute (you're doing it wrong, you have to check for the value first then remove thepx
suffix) - Make a timeout function to clone the object at
index
, then put it at the end of theslider
object (have to increase thewidth
and set theleft
style properly). The function sync exactly with the transition duration.
function sliderFunc() {
let sliderBox = document.querySelector('.slider');
let tapToRightBtn = document.querySelector('.btn');
let index = 0;
sliderBox.style.width = '500px';
sliderBox.style.left = '0px';
function sliderNext() {
setTimeout(() => {
index ;
let child = sliderBox.querySelector(`div:nth-child(${index})`);
let cloneNode = child .cloneNode(true);
sliderBox.style.width = `${(5 index) * 100}px`;
sliderBox.appendChild(cloneNode);
}, 300);
// clone and move the element to bottom
let currentLeftPosition = sliderBox.style.left ? parseFloat(sliderBox.style.left.replace('px', '')) : 0;
let nextLeftPosition = currentLeftPosition - 100;
sliderBox.style.left = `${nextLeftPosition}px`;
}
tapToRightBtn.addEventListener('click', sliderNext);
}
sliderFunc();
.container {
max-width: 300px;
margin: auto;
overflow: hidden;
position: relative;
}
.slider {
background: #eee;
display: flex;
min-width: 500px;
border: solid;
position: relative;
transition: left 0.3s;
}
.slide {
width: 200px;
height: 100px;
margin-right: 10px;
}
.slide1 {
background: #f3ca63;
}
.slide2 {
background: #d06c65;
}
.slide3 {
background: #6579d0;
}
.slide4 {
background: #65d073;
}
.slide5 {
background: #ba65d0;
}
.btn {
margin: 2rem;
}
<section >
<div >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</div>
<button >Next</button>
</section>
CodePudding user response:
ciao Stanley,
if I understood your question you can go with the following elegant solution
I will first explain the principles and advantages:
- I won't add/remove any element, working only on your initial
sliderBox
- in order to create an infinite loop I'm stopping the shift move on this element that would be executed by
sliderBox.style.transform = 'translateX(-100px)';
- I modified
sliderNext()
so that the infinite slide effect will be achieved by stealing the color to the next slide, i.e. after clicking the Next button the 2nd slide will steal the color to the 3rd, the 3rd to the 4th and the 4th will be assigned each time a random color to give that endless feeling - I'm assuming that "infinite loop" meant that we don't want to see the border of
sliderBox
that would be shown with the 5th element, so we will never see it [you can add a "Go to the last element" button should you need that] - I did only minimal adjustments to your original draft, minimizing also any unneeded computational operations
Without further ado here is the final code:
function sliderFunc() {
let sliderBox = document.querySelector('.slider');
let tapToRightBtn = document.querySelector('.btn');
let counter = 0;
let firstSlide = document.querySelector('.slide2');
let secondSlide = document.querySelector('.slide3');
let thirdSlide = document.querySelector('.slide4');
function sliderNext() {
if (counter == 0) {
sliderBox.style.transform = 'translateX(-100px)';
sliderBox.style.transition = '0.3s';
} else {
firstSlide.style.background = secondSlide.style.background;
secondSlide.style.background = thirdSlide.style.background;
thirdSlide.style.background = "#" Math.floor(Math.random() * 16777215).toString(16);
}
counter ;
}
tapToRightBtn.addEventListener('click', sliderNext);
}
sliderFunc();
.container {
max-width: 300px;
margin: auto;
overflow: hidden;
}
.slider {
background: #eee;
display: flex;
width: 500px;
border: solid;
}
.slide {
width: 200px;
height: 100px;
margin-right: 10px;
}
.slide1 {
background: #f3ca63;
}
.slide2 {
background: #d06c65;
}
.slide3 {
background: #6579d0;
}
.slide4 {
background: #65d073;
}
.slide5 {
background: #ba65d0;
}
.btn {
margin: 2rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<section >
<div >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</div>
<button >Next</button>
</section>
</body>
</html>
This should solve your problem, otherwise let me know
Have a good day,
Antonino