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 positionrelativethen moving usingleftattribute (you're doing it wrong, you have to check for the value first then remove thepxsuffix) - Make a timeout function to clone the object at
index, then put it at the end of thesliderobject (have to increase thewidthand set theleftstyle 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
sliderBoxthat 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
