Слайдер карусель
Всем привет. Есть конструктор слайдера-карусели, сейчас пытаюсь добавить точки и обозначение типа "01/04" в зависимости от текущего сайта. Направьте на правильный путь, начал с точками, но работает некорректно. Спасибо
<div class="carousel-container"> <div class="carousel-slides"> <img class="slide" id="lastClone" src="4.jpg"> <img class="slide" src="1.jpg"> <img class="slide" src="2.jpg"> <img class="slide" src="3.jpg"> <img class="slide" src="4.jpg"> <img class="slide" id="firstClone" src="1.jpg"> </div> <div class="btn-container"> <div class="btn" id="prev"> prev </div> <div class="btn" id="next"> next </div> </div> <div class="dots-container"> <div class="dot active"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> </div> .carousel-container { display: block; width: 640px; height: 320px; margin: 0 auto; overflow: hidden; position: relative; } .carousel-slides { width: 100%; height: 100%; position: relative; top: 0; left: 0; } img { width: 100%; height: 100%; } .slide { position: absolute; top: 0; } .slide:nth-child(1) { left: 0; } .slide:nth-child(2) { left: 100%; } .slide:nth-child(3) { left: 200%; } .slide:nth-child(4) { left: 300%; } .slide:nth-child(5) { left: 400%; } .slide:nth-child(6) { left: 500%; } .btn-container { display: flex; justify-content: space-between; width: 100%; position: absolute; bottom: 0; left: 0; background-color: rgba(255,138,24,0.5); } .btn { font-size: 24px; font-weight: 600; padding: 10px; cursor: pointer; } .dots-container { position: absolute; right: 20px; top: 80px; } .dot { width: 20px; height: 20px; border: 1px solid #fff; border-radius: 50%; margin: 20px; cursor: pointer; } .active { background-color: red; } //Создаем шаблон (function(){ //Для document и индекса создаем переменные var doc = document, index = 1; //Определяем конструктор слайдера var Slider = function() { //Определяем контейнер слайдера как свойство this.box = doc.querySelector('.carousel-container'); //Определяем контейнер-обертку слайдов как свойство this.slidesBox = doc.querySelector('.carousel-slides'); //Определяем непосредственно слайды как свойства this.slides = doc.querySelectorAll('.slide'); //Определяем кнопки как свойства this.btns = doc.querySelectorAll('.btn'); //Получаем значение ширины главного контейнера this.size = this.box.clientWidth; //Определяем точки this.dots = doc.querySelectorAll('.dot'); //Вызываем методы внутри контейнера this.position(); this.carousel(); this.currentSlide(); } //Создаем методы для слайдера //1. Метод для перемещения картинок на одну влево, чтобы первая картинка оказалась на своем месте Slider.prototype.position = function() { var size = this.size; this.slidesBox.style.transform = `translateX(${-index * size}px)`; }; //2. Метод переключения Slider.prototype.carousel = function() { var i, max = this.btns.length, that = this; for(i = 0; i < max; i += 1) { that.btns[i].addEventListener('click', Slider[that.btns[i].id].bind(null, that))//Slider[id кнопок, для вызова статических методов] bind - передача аргументов в статические функции, т.к. статические методы не имеют доступа в пространство конструктора, не видят его свойства } }; //3. Создаем статичные методы для кнопок Slider.prev = function(box) { box.slidesBox.style.transition = 'transform .3s ease-in-out'; var size = box.size; var dots = box.dots; index <= 0 ? false : index--; box.slidesBox.style.transform = `translateX(${-index * size}px)`; for(var i = 0; i < dots.length; i += 1) { dots[i].classList.remove('active'); } index <= 0 ? false : dots[index - 1].classList.add('active'); box.jump(); }; Slider.next = function(box) { box.slidesBox.style.transition = 'transform .3s ease-in-out'; var max = box.slides.length; var size = box.size; var dots = box.dots; index >= max - 1 ? false : index++; box.slidesBox.style.transform = `translateX(${-index * size}px)`; for(var i = 0; i < dots.length; i += 1) { dots[i].classList.remove('active'); } index >= max - 1 ? false : dots[index - 1].classList.add('active'); box.jump(); }; //Создаем метод для плавного перехода изображений Slider.prototype.jump = function() { var that = this; var size = this.size; this.slidesBox.addEventListener('transitionend', function() { that.slides[index].id === 'firstClone' ? index = 1 : index; that.slides[index].id === 'lastClone' ? index = that.slides.length - 2 : index; that.slidesBox.style.transition = 'none'; that.slidesBox.style.transform = `translateX(${-index * size}px)`; }); }; Slider.prototype.currentSlide = function() { var i, dots = this.dots; var that = this; for(i = 0; i < dots.length; i += 1) { dots[i].addEventListener('click', function() { that.carousel(); }); } }; //Вызываем конструктор new Slider(); })(); |
img { width: 100%; height: 100%; object-fit: cover; /* нужно указать, чтобы не было «искажения» картинок */ } /* ... удивительно, а если будет 104 картинки? */ .slide:nth-child(2) { left: 100%; } .slide:nth-child(3) { left: 200%; } .slide:nth-child(4) { left: 300%; } .slide:nth-child(5) { left: 400%; } .slide:nth-child(6) { left: 500%; } Вам нужно избавиться от повтора в исходном коде… удалите… <img class="slide" id="lastClone" src="4.jpg"> <img class="slide" id="firstClone" src="1.jpg"> Это вообще бессмысленно... //Для document и индекса создаем переменные var doc = document, index = 1;Должно ведь быть описано внутри класса… //Вызываем конструктор new Slider();А если ещё раз вызвать, то как будет другой экземпляр работать? Короче, вот сделал кучу исправлений... не буду их описывать, сравни, если надо, но если что-то не понятно, то можно ещё спросить в этой же теме! https://codepen.io/Malleys/pen/YzPrEwP |
Спасибо. Работает.
Перешли, пожалуйста, в виде архива, CodePan лагает, не вижу код. |
Вложений: 1
Странно! А экспорт тоже не работает(правый нижний угол)?
|
Экспорта тоже не видно. Не знаю в чем дело...
По коду, все работает, только немного некорректно отображается, кнопки слетели, и 1 of 4 вроде.. Сейчас буду разбираться, спасибо огромное. Ну у тебя тут как-то более профессионально написано |
Malleys,
почему Math.mod = function mod(a, b) { return (a % b + b) % b; }; а не Math.mod = function mod(a, b) { return (a + b) % b; }; ? |
Цитата:
|
Согласен. Точки не могу внедрить без ошибок. Может подскажете, что не так с кодом в первом сообщении. Кстати, С Новым Годом!
|
слайдер с точечной навигацией
faceVB,
Malleys, как вариант ... <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> @import url('https://fonts.googleapis.com/css?family=Parisienne&display=swap'); .carousel-container { display: block; width: 640px; height: 320px; margin: 0 auto; position: relative; overflow: hidden; background: black; } .carousel-slides { width: 100%; height: 100%; } .carousel-slides > * { width: 100%; height: 100%; object-fit: cover; position: absolute; transition: transform 1.8s cubic-bezier(0.165, 0.84, 0.44, 1); transform: translateX(-100%); } .carousel-container:hover .btn-container { opacity: 1; transform: translateY(0%); } .btn-container { display: flex; justify-content: space-between; width: 100%; position: absolute; bottom: 0; left: 0; background-color: rgba(133, 194, 255, .3); z-index: 2; opacity: 0; transform: translateY(100%); transition: .4s; } .btn-container > button { background: transparent; border: 0; padding: 10px; cursor: pointer; font: 400 2.4em / 23px "Parisienne", sans-serif; color: #FFFFFF; } .btn-container > .info { display: grid; place-content: center; } .dots-container { position: absolute; right: 20px; top: 0; bottom: 54px; z-index: 2; height: max-content; margin: auto; display: flex; flex-direction: column; } .dots-container > .dot { -webkit-appearance: none; appearance: none; width: 1em; height: 1em; border: 1px solid #fff; border-radius: 50%; cursor: pointer; display: flex; margin: 3px; filter: drop-shadow(0 0 2px black); } .dots-container > .dot:checked { background-color: rgba(240, 255, 240, .8); border: transparent; } .dots-container > .dot:focus, .btn-container > button { outline: none; } .info{ color: #FFFFFF; font: 400 1.2em / 23px "Parisienne", sans-serif; } </style> </head> <body> <div class="carousel-container"> <div class="carousel-slides"> <img src="https://picsum.photos/640/320?1"> <img src="https://picsum.photos/640/320?2"> <img src="https://picsum.photos/640/320?3"> <img src="https://picsum.photos/640/320?4"> <img src="https://picsum.photos/640/320?5"> <img src="https://picsum.photos/640/320?6"> <img src="https://picsum.photos/640/320?7"> <img src="https://picsum.photos/640/320?8"> </div> <div class="btn-container"> <button data-step="-1"><</button> <section class="info">1 of 4</section> <button data-step="1">></button> </div> <div class="dots-container"></div> </div> <script> (function() { function Slider(carouselContainer) { this.slides = Array.from(carouselContainer.querySelectorAll(".carousel-slides > *")); this.btns = carouselContainer.querySelector(".btn-container"); this.info = carouselContainer.querySelector(".btn-container > .info"); var dotsContainer = carouselContainer.querySelector(".dots-container"); this.currentSlider = this.slides[1]; this.dots = this.slides.map(function(slide, index) { var dot = document.createElement("input"); dot.type = "radio"; dot.name = "slider-" + Slider.id; dot.className = "dot"; dot.setAttribute("data-slide", index); dotsContainer.appendChild(dot); return dot; }); this.btns.addEventListener("click", (function(event) { var button = event.target.closest("[data-step]"); if(!button) return; var step = Number(button.getAttribute("data-step")); this.go(Math.mod(this.index + step, this.slides.length)); }).bind(this)); dotsContainer.addEventListener("change", (function(event) { var index = Number(event.target.getAttribute("data-slide")); this.go(index); }).bind(this)); this.index = 0; this.go(0); Slider.id++; } Slider.id = 0; Slider.prototype.go = function(index) { var X = index > this.index ? 100 : -100; if(!index && this.index == this.slides.length - 1) X = 100; if(index == this.slides.length - 1 && !this.index) X = -100; this.index = index; this.dots[this.index].checked = true; this.info.textContent = (this.index + 1) + " of " + this.slides.length; this.nextSlider = this.slides[this.index]; this.nextSlider.style.transition = "none"; this.nextSlider.style.transform = `translateX(${X}%)`; document.documentElement.clientWidth; this.nextSlider.style.transition = ""; this.nextSlider.style.transform = `translateX(0%)`; this.currentSlider.style.transform = `translateX(${-X}%)`; [this.currentSlider, this.nextSlider] = [this.nextSlider, this.currentSlider]; }; Math.mod = function mod(a, b) { return (a + b) % b; }; Array.from(document.querySelectorAll(".carousel-container")).forEach(function(container) { new Slider(container); }); })(); </script> </body> </html> |
Цитата:
смена одного слайда на другой 1 без анимации (нажать 1 и 3 точку попеременно) 2 анимация только одного (нажимать последовательно на точки) 3 нормальная (вероятно только после прогона по всем слайдам, кнопками next или prev) может как-то единообразно сделать? |
Часовой пояс GMT +3, время: 16:31. |