JSFiddle - React, Tailwind, and code Playground
by Boba Poshtar
HTML
<div class="slider">
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/1.png" alt="slide 1">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/2.png" alt="slide 2">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/3.png" alt="slide 3">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/4.png" alt="slide 4">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/5.png" alt="slide 5">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/6.png" alt="slide 1">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/7.png" alt="slide 2">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/8.png" alt="slide 3">
</div>
<div class="item">
<img src="https://poshtarboba.github.io/fe/tmp/9.png" alt="slide 4">
</div>
<span class="prev">❮</span>
<span class="next">❯</span>
</div>
<div class="slider-dots">
<span class="slider-dots_item" data-item="0"></span>
<span class="slider-dots_item" data-item="1"></span>
<span class="slider-dots_item" data-item="2"></span>
</div>
CSS
.slider {
position: relative;
margin: 0 auto;
width: 396px;
font-size: 0;
line-height: 0;
white-space: nowrap;
border: 2px solid silver;
}
.slider .item {
position: relative;
display: inline-block;
left: 0;
padding: 2px;
}
.slider .item.active {
transition: left 500ms;
}
.slider .prev,
.slider .next {
position: absolute;
top: 50px;
z-index: 50;
font-size: 30px;
line-height: 30px;
cursor: pointer;
}
.slider .prev {
left: 8px;
}
.slider .next {
right: 8px;
}
.slider-dots {
padding: 8px 0;
text-align: center;
}
.slider-dots_item {
display: inline-block;
width: 16px;
height: 16px;
border: 1px solid silver;
border-radius: 50%;
cursor: pointer;
}
.slider-dots_item.active {
background: silver;
}
JavaScript
(function (){
let slidesForSlide = 3;
let slides = document.querySelectorAll(".slider .item");
// перевірка чи правильна кількість слайдів
if (slides.length === 0) {
return console.log('Slides not found');
}
if (slides.length % slidesForSlide !==0) {
return console.log('Count of slides is not a multiple of ' + slidesForSlide);
}
// мета-слайд - пакет з трьох слайдів
let activeMetaSlide = 0;
let metaSlideCount = slides.length / slidesForSlide;
// взнати ширину одного слайда, зберегти у змінну.
let slideWidth = slides[0].offsetWidth;
let sliderWidth = slideWidth * slidesForSlide;
// першим N слайдам дати клас active
for (let i = 0; i < slidesForSlide; i++) {
slides[i].classList.add("active");
}
// при кліку на стрілку вліво:
document.querySelector(".slider .prev").onclick = function (){
slideWidth = slides[0].offsetWidth;
sliderWidth = slideWidth * slidesForSlide;
// змінюємо мета-слайд на попередній
activeMetaSlide--;
if (activeMetaSlide < 0) {
activeMetaSlide = metaSlideCount - 1;
}
// поточні активні слайди зсовуємо вліво на ширину слайдера
slides.forEach(function (elem){
if (elem.classList.contains('active')) {
elem.style.left = -sliderWidth + 'px';
}
});
// знаходимо слайди з нового мета-слайда і ставимо їх справа від слайдера
// добавляємо клас active який посуне їх на центр екрана стилями
let n = activeMetaSlide * slidesForSlide;
for (let i = 0; i < slidesForSlide; i++) {
slides[n + i].style.left = sliderWidth + 'px';
slides[n + i].classList.add('active');
}
};
// при кліку на стрілку вправо:
document.querySelector(".slider .next").onclick = function (){
slideWidth = slides[0].offsetWidth;
sliderWidth = slideWidth * slidesForSlide;
// змінюємо мета-слайд на попередній
activeMetaSlide++;
if (activeMetaSlide >= metaSlideCount) {
activeMetaSlide = 0;
}
// поточні активні слайди зсовуємо вліво на ширину слайдера
slides.forEach(function (elem){
if (elem.classList.contains('active')) {
...