Слайдеры — неотъемлемая часть современного веба, но зачем тянуть тяжёлую библиотеку ради нескольких изображений? В этом руководстве мы с нуля создадим карусель на чистом JavaScript, разберём механику переключения, добавим плавные анимации и пагинацию, а вы поймёте, что иногда лучший инструмент — тот, что сделали вы сами.
Зачем писать слайдер самостоятельно?
Библиотеки вроде Slick или Swiper — это удобно, но они добавляют лишние килобайты, могут конфликтовать с вашим кодом и часто содержат функционал, который вам не нужен. Свой слайдер будет легковесным, полностью контролируемым и отличным упражнением для понимания DOM, событий и CSS-анимаций.
Слайдер, созданный с нуля, обычно весит менее 5 КБ против 50+ КБ у популярных библиотек (без учёта зависимостей).
Структура HTML: основа карусели
Начнём с разметки. Нам понадобится контейнер, обёртка для слайдов и сами слайды.
<div class="slider-container">
<div class="slider-track">
<div class="slide"><img src="slide1.jpg" alt=""></div>
<div class="slide"><img src="slide2.jpg" alt=""></div>
<div class="slide"><img src="slide3.jpg" alt=""></div>
</div>
<button class="slider-btn prev">❮</button>
<button class="slider-btn next">❯</button>
<div class="slider-dots"></div>
</div>
Ключевые CSS-стили
С помощью CSS мы скроем всё, что выходит за пределы контейнера, и расположим слайды горизонтально.
.slider-container {
position: relative;
overflow: hidden;
max-width: 800px;
margin: 0 auto;
}
.slider-track {
display: flex;
transition: transform 0.5s ease-in-out;
}
.slide {
min-width: 100%;
height: 400px;
object-fit: cover;
}
JavaScript: оживляем механику
Теперь самое интересное — логика переключения. Создадим объект слайдера с основными методами.
class SimpleSlider {
constructor(containerSelector) {
this.container = document.querySelector(containerSelector);
this.track = this.container.querySelector('.slider-track');
this.slides = Array.from(this.track.children);
this.currentIndex = 0;
this.initControls();
this.updateTrack();
}
moveTo(index) {
if (index < 0) index = this.slides.length - 1;
if (index >= this.slides.length) index = 0;
this.currentIndex = index;
this.updateTrack();
}
updateTrack() {
const offset = -this.currentIndex * 100;
this.track.style.transform = `translateX(${offset}%)`;
}
initControls() {
const nextBtn = this.container.querySelector('.next');
const prevBtn = this.container.querySelector('.prev');
nextBtn.addEventListener('click', () => this.moveTo(this.currentIndex + 1));
prevBtn.addEventListener('click', () => this.moveTo(this.currentIndex - 1));
}
}
// Инициализация
new SimpleSlider('.slider-container');
Используйте CSS-переход (transition) для анимации вместо JavaScript-интервалов. Это производительнее и плавнее.
Добавляем индикаторы и автопрокрутку
Слайдер без точек навигации и автопереключения — неполноценный. Реализуем эти функции.
Создание точек-индикаторов
createDots() {
const dotsContainer = this.container.querySelector('.slider-dots');
this.slides.forEach((_, index) => {
const dot = document.createElement('button');
dot.classList.add('dot');
dot.addEventListener('click', () => this.moveTo(index));
dotsContainer.appendChild(dot);
});
this.updateDots();
}
updateDots() {
const dots = this.container.querySelectorAll('.dot');
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === this.currentIndex);
});
}
Автопрокрутка с паузой при наведении
startAutoPlay(interval = 3000) {
this.autoPlayInterval = setInterval(() => {
this.moveTo(this.currentIndex + 1);
}, interval);
this.container.addEventListener('mouseenter', () => clearInterval(this.autoPlayInterval));
this.container.addEventListener('mouseleave', () => this.startAutoPlay(interval));
}
Оптимизация и расширение функционала
Готовый слайдер можно улучшить:
- Добавить touch-события для свайпов на мобильных устройствах.
- Реализовать бесконечную прокрутку через клонирование крайних слайдов.
- Добавить ленивую загрузку изображений для повышения производительности.
- Создать переходы с fade-эффектом вместо горизонтального сдвига.
FAQ: частые вопросы о самописных слайдерах
Сложно ли сделать слайдер на чистом JS?
Нет, базовая реализация занимает около 50 строк кода. Главное — понять принцип работы transform и управления DOM.
Будет ли такой слайдер работать в старых браузерах?
Да, если использовать подход с изменением margin-left вместо transform для анимации, но это менее производительно.
Как добавить вертикальную прокрутку?
Замените translateX на translateY и измените flex-direction у .slider-track на column.
Почему слайдер дёргается при быстром клике?
Добавьте флаг isAnimating, который блокирует обработку событий во время перехода.
Как реализовать адаптивность?
Используйте CSS-медиазапросы для изменения размеров .slider-container и обновляйте расчёты в JavaScript при resize.