Прочитав эту статью решил запилить свою карусель с блэк-джеком и jQuery хотя нет, без него ибо 2017 год и он не особо и нужен. Создадим функцию, которая принимает объект с параметрами и делает слайдер. Некоторые моменты будут опущены, такие как: вендорные префиксы, таймер смены и т.д.
Первое что мы сделаем — разметка для карусели, на классах, а не id, дабы можно было использовать несколько раз один и тот же модуль на странице, ну и специфичность не была 3-его порядка.
<div class="wrap"> <div class="b-carousel js-carousel"> <buttom class="b-carousel__prev js-carousel__prev">Prev</buttom> <buttom class="b-carousel__next js-carousel__next">Next</buttom> <div class="b-carousel__wrap js-carousel__wrap"> <div class="b-carousel__item"> <img src="..." alt="" class="b-carousel__img"> </div> <div class="b-carousel__item"> <img src="..." alt="" class="b-carousel__img"> </div> <div class="b-carousel__item"> <img src="..." alt="" class="b-carousel__img"> </div> <div class="b-carousel__item"> <img src="..." alt="" class="b-carousel__img"> </div> </div> </div> </div>
У нас есть:
- Блок — обертка для карусели, который скрывает все, что вылезает за его рамки;
- Контейнер для самих слайдов, которые будут располагаться в строчку, с помощью flexbox, можем себе это позволить;
- Блоки слайдов, которые скрывают все, что вылезает за их границы;
- Блок – хелпер для выравнивания картинки по вертикали. И, внутри него уже будем располагать картинки.
В CSS используем БЭМ нотификацию, ибо не засоряем глобальную область. Сделаем его чуть-чуть адаптивным.
.b-carousel { width: 100%; overflow: hidden; position: relative; box-sizing: border-box; border: 1px solid; } .b-carousel__prev, .b-carousel__next { position: absolute; top: 50%; left: 20px; width: 50px; height: 50px; background: #fff; transform: translateY(-50%) translateZ(0); cursor: pointer; text-indent: 100%; white-space: nowrap; overflow: hidden; z-index: 3; } .b-carousel__next { left: auto; right: 20px; } .b-carousel__wrap { display: flex; transition: transform .5s; will-change: transform; position: relative; z-index: 1; height: 100%; } .b-carousel__item { flex: 0 0 100%; overflow: hidden; display: flex; align-items: center; justify-content: center; } .b-carousel__img { width: 100%; display: block; }
Transform: translateZ(0) у контролов — хак для вынесения их на отдельный композитный слой, чтобы при смещении контейнера со слайдами не было перерисовки кнопок. А у обертки свойство will-change. Оно для броузера, чтобы он знал, что с блоком будут происходить какие-то действия.
Да начнем писать код. Создадим функцию, которая принимает объект с параметрами:
function Carousel(setting) { /* Scope privates methods and properties */ let privates = {}; /* Privates properties */ privates.setting = setting; privates.sel = { "main": document.querySelector(privates.setting.main), "wrap": document.querySelector(privates.setting.wrap), "children": document.querySelector(privates.setting.wrap).children, "prev": document.querySelector(privates.setting.prev), "next": document.querySelector(privates.setting.next) }; privates.opt = { "position": 0, "max_position": document.querySelector(privates.setting.wrap).children.length }; // Control if(privates.sel.prev !== null) { privates.sel.prev.addEventListener('click', () => { this.prev_slide(); }); } if(privates.sel.next !== null) { privates.sel.next.addEventListener('click', () => { this.next_slide(); }); } }
Методы для управления ей:
/* Public methods */ // Prev slide this.prev_slide = () => { --privates.opt.position; if(privates.opt.position < 0) { privates.sel.wrap.classList.add('s-notransition'); privates.opt.position = privates.opt.max_position - 1; } privates.sel.wrap.style["transform"] = `translateX(-${privates.opt.position}00%)`; }; // Next slide this.next_slide = () => { ++privates.opt.position; if(privates.opt.position >= privates.opt.max_position) { privates.opt.position = 0; } privates.sel.wrap.style["transform"] = `translateX(-${privates.opt.position}00%)`; };
Методы next_slide и prev_slide будут двигать обертку с помощью transform, дабы не было перерисовки блока, и анимация происходила на GPU.
Делаем карусель:
new Carousel({ "main": ".js-carousel", "wrap": ".js-carousel__wrap", "prev": ".js-carousel__prev", "next": ".js-carousel__next" });
Если не все знают
Это все! Меньше кода — меньше трафика (jQuery 3.1 ~34kB). Контроль над параметрами и можем использовать несколько раз на странице.
Демо:
Если понравилась статья, то в скором времени будет продолжение с цикличной анимацией, touch-событиями и еще многими вкусными плюшками!
ссылка на оригинал статьи https://habrahabr.ru/post/327246/
Добавить комментарий