Слайдер на html автопрокруткой

JavaScript. Простой слайдер

Простой слайдер на чистом css и javascript, не имеет практической ценности, исключительно для практики. Несколько картинок, возможность автопрокрутки, кнопки вперед и назад, индикатор текущего слайда. Для начала подготовим простую страницу, создадим html-разметку и файл стилей — а потом напишем js-класс Slider .

 lang="en"> charset="UTF-8"> http-equiv="X-UA-Compatible" content="IE=edge"> name="viewport" content="width=device-width, initial-scale=1.0"> Slider  *  box-sizing: border-box; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; > .container  max-width: 900px; margin: 0px auto; >   rel="stylesheet" href="slider.css"> src="slider.js">   document.addEventListener('DOMContentLoaded', function()  // здесь будем создавать экземпляр js-класса слайдера >);    class="container">  

Создаем html-разметку слайдера

 class="container"> class="carousel"> class="carousel-window"> class="carousel-slides"> class="carousel-item"> src="img/slide-1.jpg" alt="">  class="carousel-item"> src="img/slide-2.jpg" alt="">  class="carousel-item"> src="img/slide-3.jpg" alt="">  class="carousel-item"> src="img/slide-4.jpg" alt="">  class="carousel-item"> src="img/slide-5.jpg" alt="">    href="#" class="carousel-prev"> class="carousel-prev-icon"><   href="#" class="carousel-next"> class="carousel-next-icon">>     

Создаем файл стилей слайдера

.carousel < margin: 0 auto; position: relative; >.carousel .carousel-indicators < position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); z-index: 15; display: flex; justify-content: center; padding: 10px; list-style: none; >.carousel .carousel-indicators li < flex: 0 1 auto; width: 20px; height: 20px; margin-right: 5px; margin-left: 5px; cursor: pointer; background-color: #343a40; border: 2px solid #fff; border-radius: 50%; >.carousel .carousel-indicators .active < background-color: #025fff; >.carousel .carousel-window < width: 100%; height: 500px; position: relative; overflow: hidden; >.carousel .carousel-slides < height: 100%; display: flex; transition: transform 0.5s; >.carousel .carousel-item < height: 100%; >.carousel .carousel-item img < width: 100%; height: 100%; object-fit: cover; >.carousel .carousel-prev, .carousel .carousel-next < position: absolute; top: 0; bottom: 0; z-index: 1; display: flex; justify-content: center; align-items: center; width: 15%; color: #fff; opacity: 0.7; text-align: center; font-size: 40px; text-decoration: none; >.carousel .carousel-prev:hover, .carousel .carousel-next:hover < opacity: 1; background-color: rgba(0, 0, 0, 0.2); >.carousel .carousel-prev < left: 0; >.carousel .carousel-next
/* * 
width: 100% (от контейнера .container 900px) *
width: 100% (от родителя 900px); height: 500px *
display: flex, style.width = 300% (2700px) *
.
style.width = 33.33333% (900px) *
.
style.width = 33.33333% (900px) *
.
style.width = 33.33333% (900px) *
*
*
* Можно сказать, что carousel-window представляет собой окно просмотра 900x500px, * в этом окне просмотра виден одновременно только один кадр (слайд). Элемент * carousel-slides представляет из себя цепочку из трех кадров (как в кино). Эти * кадры выстроены по горизонтали благодаря display:flex. При клике на кнопки * next и prev — цепочка смещается влево, и в окне просмотра появляется очередной * кадр (слайд). */
class Slider constructor(slider, autoplay = true) // элемент div.carousel this.slider = slider; // все кадры (слайды) this.allFrames = slider.querySelectorAll('.carousel-item'); // цепочка кадров this.frameChain = slider.querySelector('.carousel-slides'); // кнопка «вперед» this.nextButton = slider.querySelector('.carousel-next'); // кнопка «назад» this.prevButton = slider.querySelector('.carousel-prev'); this.index = 0; // индекс кадра, который сейчас в окне просмотра this.length = this.allFrames.length; // сколько всего есть кадров this.autoplay = autoplay; // включить автоматическую прокрутку? this.paused = null; // чтобы можно было выключать автопрокрутку this.init(); // инициализация слайдера > init() this.dotButtons = this.dots(); // создать индикатор текущего кадра // все кадры должны быть одной ширины, равной ширине окна просмотра; // если кадров три, то ширина каждого кадра будет 100/3 = 33.33333% // от ширины контейнера .carousel-slides, то есть 900 пикселей this.allFrames.forEach(frame => frame.style.width = 100/this.length + '%'); // ширина цепочки кадров должна равна ширине всех кадров, то есть // 900*3 = 2700 пикселей; но удобнее задать в процентах от родителя, // если кадров три, то ширина контейнера кадров будет 100*3 = 300% this.frameChain.style.width = 100 * this.length + '%'; this.nextButton.addEventListener('click', event => // клик по кнопке «вперед» event.preventDefault(); this.next(); >); this.prevButton.addEventListener('click', event => // клик по кнопке «назад» event.preventDefault(); this.prev(); >); // клики по кнопкам индикатора текущего кадра this.dotButtons.forEach(dot => dot.addEventListener('click', event => event.preventDefault(); const index = this.dotButtons.indexOf(event.target); if (index === this.index) return; this.goto(index); >); >); if (this.autoplay) // включить автоматическую прокрутку? this.play(); // когда мышь над слайдером — останавливаем автоматическую прокрутку this.slider.addEventListener('mouseenter', () => clearInterval(this.paused)); // когда мышь покидает пределы слайдера — опять запускаем прокрутку this.slider.addEventListener('mouseleave', () => this.play()); > > // перейти к кадру с индексом index goto(index) // изменить текущий индекс. if (index > this.length - 1) this.index = 0; > else if (index 0) this.index = this.length - 1; > else this.index = index; > // . и выполнить смещение this.move(); > // перейти к следующему кадру next() this.goto(this.index + 1); > // перейти к предыдущему кадру prev() this.goto(this.index - 1); > // рассчитать и выполнить смещение move() // на сколько нужно сместить, чтобы нужный кадр попал в окно const offset = 100/this.length * this.index; this.frameChain.style.transform = `translateX(-$ %)`; this.dotButtons.forEach(dot => dot.classList.remove('active')); this.dotButtons[this.index].classList.add('active'); > // запустить автоматическую прокрутку play() this.paused = setInterval(() => this.next(), 3000); > // создать индикатор текущего слайда dots() const ol = document.createElement('ol'); ol.classList.add('carousel-indicators'); const children = []; for (let i = 0; i this.length; i++) let li = document.createElement('li'); if (i === 0) li.classList.add('active'); ol.append(li); children.push(li); > this.slider.prepend(ol); return children; > >

Создаем экземпляр js-класса

rel="stylesheet" href="slider.css"> src="slider.js">   document.addEventListener('DOMContentLoaded', function()  new Slider(document.querySelector('.carousel')); >);  

Еще одни вариант

Еще один вариант слайдера, который допускает показ в каждом кадре нескольких элементов. Кроме того, можно указать, на сколько элементов сдвигать, чтобы показать следующий кадр.

/* * 
width: 100% (от контейнера .container 900px) *
width: 100% (от родителя 900px); height: 500px *
display: flex, style.width = 300% (2700px) *
.
style.width = 33.33333% (900px) *
.
style.width = 33.33333% (900px) *
.
style.width = 33.33333% (900px) *
*
*
*/
class Slider constructor(slider, autoplay = true, inFrame = 1, offset = 1> = >) // элемент div.carousel this.slider = slider; // кол-во элементов в одном кадре this.inFrame = inFrame; // на сколько элементов смещать this.offset = offset; // все элементы слайдера this.allItems = slider.querySelectorAll('.carousel-item'); // сколько всего элементов this.itemCount = this.allItems.length; // все кадры слайдера this.allFrames = this.frames(); // сколько всего кадров this.frameCount = this.allFrames.length; // индекс кадра в окне просмотра this.frameIndex = 0; // контейнер для элементов this.wrapper = slider.querySelector('.carousel-slides'); // кнопка «вперед» this.nextButton = slider.querySelector('.carousel-next'); // кнопка «назад» this.prevButton = slider.querySelector('.carousel-prev'); this.autoplay = autoplay; // включить автоматическую прокрутку? this.paused = null; // чтобы можно было выключать автопрокрутку this.init(); // инициализация слайдера > init() this.dotButtons = this.dots(); // создать индикатор текущего кадра // если всего 10 элементов, то ширина одного элемента составляет 1/10 // ширины контейнера .carousel-slides, то есть 100/10 = 10% this.allItems.forEach(item => item.style.width = 100 / this.itemCount + '%'); // ширина контейнера должна вмещать все элементы: если элементов 10, // в окне просмотра 3 элемента, тогда ширина контейнера равна ширине // трех окон просмотра (300%) плюс ширина одного элемента 33.33333%, let wrapperWidth = this.itemCount / this.inFrame * 100; this.wrapper.style.width = wrapperWidth + '%'; this.nextButton.addEventListener('click', event => // клик по кнопке «вперед» event.preventDefault(); this.next(); >); this.prevButton.addEventListener('click', event => // клик по кнопке «назад» event.preventDefault(); this.prev(); >); // клики по кнопкам индикатора текущего кадра this.dotButtons.forEach(dot => dot.addEventListener('click', event => event.preventDefault(); const frameIndex = this.dotButtons.indexOf(event.target); if (frameIndex === this.frameIndex) return; this.goto(frameIndex); >); >); if (this.autoplay) // включить автоматическую прокрутку? this.play(); // когда мышь над слайдером — останавливаем автоматическую прокрутку this.slider.addEventListener('mouseenter', () => clearInterval(this.paused)); // когда мышь покидает пределы слайдера — опять запускаем прокрутку this.slider.addEventListener('mouseleave', () => this.play()); > > // перейти к кадру с индексом index goto(index) if (index > this.frameCount - 1) this.frameIndex = 0; > else if (index 0) this.frameIndex = this.frameCount - 1; > else this.frameIndex = index; > // . и выполнить смещение this.move(); > // перейти к следующему кадру next() this.goto(this.frameIndex + 1); > // перейти к предыдущему кадру prev() this.goto(this.frameIndex - 1); > // рассчитать и выполнить смещение move() // на сколько нужно сместить, чтобы нужный кадр попал в окно const offset = 100 / this.itemCount * this.allFrames[this.frameIndex]; this.wrapper.style.transform = `translateX(-$ %)`; this.dotButtons.forEach(dot => dot.classList.remove('active')); this.dotButtons[this.frameIndex].classList.add('active'); > // запустить автоматическую прокрутку play() this.paused = setInterval(() => this.next(), 3000); > // создать индикатор текущего кадра dots() const ol = document.createElement('ol'); ol.classList.add('carousel-indicators'); const children = []; for (let i = 0; i this.frameCount; i++) let li = document.createElement('li'); if (i === 0) li.classList.add('active'); ol.append(li); children.push(li); > this.slider.prepend(ol); return children; > // индекс первого элемента каждого кадра frames() // все наборы элементов, которые потенциально могут быть кадрами let temp = []; for (let i = 0; i this.itemCount; i++) // этот набор из this.inFrame элементов без пустого места if (this.allItems[i + this.inFrame - 1] !== undefined) temp.push(i); > > // с учетом того, что смещение this.offset может быть больше 1, // реальных кадров будет меньше или столько же let allFrames = []; for (let i = 0; i temp.length; i = i + this.offset) allFrames.push(temp[i]); > // в конце могут быть элементы, которые не могут образовать целый кадр (без пустоты), // такой кадр вообще не попадает в окно просмотра; вместо него показываем последний // целый кадр из числа потенциальных; при этом смещение будет меньше this.offset if (allFrames[allFrames.length - 1] !== temp[temp.length - 1]) allFrames.push(temp[temp.length - 1]); > return allFrames; > >
rel="stylesheet" href="slider.css"> src="slider.js">   document.addEventListener('DOMContentLoaded', function()  new Slider(document.querySelector('.carousel'),  inFrame: 2, // два элемента в кадре offset: 1, // смещать на один элемент >); >);  

Источник

Читайте также:  Php получить все параметры get запрос
Оцените статью