Бесконечный слайдер на чистом JS
Делаю слайдер на чистом JS с помощью setInterval. Как можно добиться бесконечной прокрутки слайдов?
let sliderWrapper = document.querySelector(".slider-wrapper");
let sliderElements = document.querySelectorAll(".slider-item");
const sliderItemWidth = sliderElements[0].clientWidth;
let counter = 1;
let translation = 0;
const nextSlide = function() {
let start = Date.now(); // запомнить время начала
let timer = setInterval(function() {
let timePassed = Date.now() - start;
nextBtn.classList.add("inactive-button");
if (timePassed > sliderItemWidth) {
setTimeout(() => {
nextBtn.classList.remove("inactive-button");
}, 400);
clearInterval(timer);
translation = sliderItemWidth * counter;
counter++;
return;
}
draw(timePassed);
}, 0);
function draw(timePassed) {
sliderElements.forEach((item) => {
item.style.right = translation + timePassed + "px";
});
}
};
const prevSlide = function() {
let start = Date.now();
let timer = setInterval(function() {
let timePassed = Date.now() - start;
prevBtn.classList.add("inactive-button");
if (timePassed > sliderItemWidth + 1) {
setTimeout(() => {
prevBtn.classList.remove("inactive-button");
}, 400);
clearInterval(timer);
translation = sliderItemWidth * (counter - 2);
counter--;
return;
}
draw(timePassed);
}, 0);
function draw(timePassed) {
sliderElements.forEach((item) => {
item.style.right = translation - timePassed + "px";
});
}
};
nextBtn.addEventListener("click", nextSlide);
prevBtn.addEventListener("click", prevSlide);
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
color: #fff;
}
.main {
display: flex;
justify-content: center;
align-items: center;
}
.slider {
position: relative;
overflow: hidden;
width: 800px;
}
.slider-wrapper {
display: flex;
}
.slider-item {
flex: 0 0 100%;
max-width: 100%;
position: relative;
}
.slider-item-content {
height: 250px;
background: coral;
}
.slider-control {
position: absolute;
top: 50%;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
color: #fff;
text-align: center;
opacity: 0.5;
height: 50px;
transform: translateY(-50%);
background: rgba(0, 0, 0, .5);
}
.slider-control:hover,
.slider-control:focus {
color: #fff;
text-decoration: none;
outline: 0;
opacity: .9;
}
.slider-control-left {
left: 0;
}
.slider-control-right {
right: 0;
}
.slider-control::before {
content: '';
display: inline-block;
width: 20px;
height: 20px;
background: transparent no-repeat center center;
background-size: 100% 100%;
}
.slider-control-left::before {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E");
}
.slider-control-right::before {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E");
}
.slider-item>div {
line-height: 250px;
font-size: 100px;
text-align: center;
}
.inactive-button {
pointer-events: none;
cursor: default;
opacity: 0.1;
}
<div class="main">
<div class="slider">
<div class="slider-wrapper">
<div class="slider-item">
<div class="slider-item-content" style="background-color: aqua;">
1
</div>
</div>
<div class="slider-item">
<div class="slider-item-content" style="background-color: orange;">
2
</div>
</div>
<div class="slider-item">
<div class="slider-item-content" style="background-color: greenyellow;">
3
</div>
</div>
<div class="slider-item">
<div class="slider-item-content" style="background-color: violet;">
4
</div>
</div>
</div>
<a id="prevBtn" class="slider-control slider-control-left" href="#" role="button"></a>
<a id="nextBtn" class="slider-control slider-control-right slider-control-show" href="#" role="button"></a>
</div>
</div>
Ответы (1 шт):
Автор решения: Алексей Шиманский
→ Ссылка
Логика такова:
- Если кликаем на промотку вперёд и
counterстановится больше, чем общее количество фото, то скидываем его на 1. И дальше отображаем последнее фото на основе получившегося значения счётчика - Если кликаем на промотку назад и
counterстановится меньше 1, то устанавливаем счётчик на "количество фото". И дальше отображаем последнее фото на основе получившегося значения счётчика