Доработать слайдер на JS
Написал слайдер на чистом js (просто чтобы не пользоваться сторонними библиотеками)
function sliderLogic(sliderName, slideVisible, dots, buttons, autoPlay, timeAnimation, autoPlayTime) {
const sliderWpar = document.querySelector(sliderName);
const slider = sliderWpar.querySelector('.slider__line');
const dotsWrapper = sliderWpar.querySelector('.dots');
const buttonsWrapper = sliderWpar.querySelector('.buttons');
const slides = sliderWpar.querySelectorAll('.slider__item');
const slidesCount = slides.length;
const sliderBoxWidth = sliderWpar.querySelector('.slider').offsetWidth;
let slideWidth;
let countMovie = 0;
let dotCount = slidesCount - slideVisible + 1;
let activeDot;
if (autoPlay) {
autoPlay = setInterval(function() {
nextin(slideWidth);
}, autoPlayTime);
}
slider.style.cssText = `
position: relative;
left: 0;
display: flex;
align-items: center;
transition: all ` + timeAnimation + `s ease-in;
`
slides.forEach(item => {
slideWidth = sliderBoxWidth / slideVisible;
item.style.width = slideWidth + 'px';
});
function goSlide(n) {
countMovie = countMovie - n;
if (countMovie < -((slideWidth * slides.length) - (slideVisible * slideWidth))) {
countMovie = 0;
}
if (countMovie > 0) {
countMovie = -(slideWidth * slides.length) - -(slideVisible * slideWidth);
}
dotsElems.forEach(elem => {
elem.classList.remove('active');
});
activeDot = countMovie / -slideWidth;
if (dots) {
dotsElems[activeDot].classList.add('active');
}
slider.style.left = countMovie + 'px';
}
function nextin(n) {
goSlide(n);
}
function previous(n) {
goSlide(-n);
}
if (dots) {
let dot = '';
for (let i = 0; i < dotCount; i++) {
dot += '<span class="dots__item"></span>'
}
dotsWrapper.innerHTML = dot;
}
let dotsElems = sliderWpar.querySelectorAll('.dots__item');
dotsElems.forEach((item, i) => {
if (countMovie == 0) {
dotsElems[0].classList.add('active');
}
item.addEventListener('click', function() {
clearInterval(autoPlay);
dotsElems.forEach(elem => {
elem.classList.remove('active');
});
this.classList.add('active');
countMovie = 0 - (i * slideWidth);
slider.style.left = countMovie + 'px';
});
});
if (buttons) {
const nextButton = document.createElement('button');
nextButton.classList.add('next');
nextButton.innerText = 'next';
const prevButton = document.createElement('button');
prevButton.classList.add('prev');
prevButton.innerText = 'prev';
buttonsWrapper.append(prevButton, nextButton);
nextButton.addEventListener('click', () => {
nextin(slideWidth);
clearInterval(autoPlay);
});
prevButton.addEventListener('click', () => {
previous(slideWidth);
clearInterval(autoPlay);
});
}
}
// sliderLogic(селектор обертки слайдера, кол-во видимых слайдов, показывать точки или нет, показывать кнопки или нет, включить автопрокрутку или нет, время анимации прокрутки слайдов, интервал автопрокрутки)
sliderLogic('.wrapper', 2, true, true, false, 1, 1000);
sliderLogic('.wrapper-2', 4, true, true, true, 0.5, 1000);
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper,
.wrapper-2 {
width: 800px;
margin: 0 0 30px 0;
}
.slider {
width: 100%;
margin: 0 0 20px 0;
border: 1px solid;
overflow: hidden;
box-sizing: border-box;
}
.slider__item {
flex-shrink: 0;
padding: 5px;
box-sizing: border-box;
}
.slider__item img {
display: block;
width: 100%;
}
.dots {
margin: 30px 0;
}
.dots__item {
width: 10px;
height: 10px;
margin: 5px 7px;
padding: 0;
display: inline-block;
background: #bbb;
border-radius: 5px;
cursor: pointer;
}
.active {
background: #000 !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Slider translate vanilla js</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<div class="slider">
<div class="slider__line">
<div class="slider__item">
<img src="https://tes-game.ru/_nw/14/08884847.jpg" alt="">1
</div>
<div class="slider__item">
<img src="https://xage.ru/media/posts/2019/8/26/26-minutes-of-gameplay-dying-light-2-in-4k-trailer_BOLSTko.jpg" alt="">2
</div>
<div class="slider__item">
<img src="https://free4kwallpapers.com/uploads/originals/2020/05/02/game-art-wallpaper.jpg" alt="">3
</div>
<div class="slider__item">
<img src="https://images.hdqwalls.com/wallpapers/bthumb/resident-evil-2-2019-4k-5a.jpg" alt="">4
</div>
<div class="slider__item">
<img src="https://gamespot1.cbsistatic.com/uploads/screen_kubrick/1406/14063904/3477799-7716868968-far-c.jpg" alt="">5
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">6
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">7
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">8
</div>
</div>
</div>
<div class="dots"></div>
<div class="buttons"></div>
</div>
<div class="wrapper-2">
<div class="slider">
<div class="slider__line">
<div class="slider__item">
<img src="https://tes-game.ru/_nw/14/08884847.jpg" alt="">1
</div>
<div class="slider__item">
<img src="https://xage.ru/media/posts/2019/8/26/26-minutes-of-gameplay-dying-light-2-in-4k-trailer_BOLSTko.jpg" alt="">2
</div>
<div class="slider__item">
<img src="https://free4kwallpapers.com/uploads/originals/2020/05/02/game-art-wallpaper.jpg" alt="">3
</div>
<div class="slider__item">
<img src="https://images.hdqwalls.com/wallpapers/bthumb/resident-evil-2-2019-4k-5a.jpg" alt="">4
</div>
<div class="slider__item">
<img src="https://gamespot1.cbsistatic.com/uploads/screen_kubrick/1406/14063904/3477799-7716868968-far-c.jpg" alt="">5
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">6
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">7
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">8
</div>
</div>
</div>
<div class="dots"></div>
<div class="buttons"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Только вот не знаю как решить след. проблему.
Все опции для его работы я сделал параметрами и при объявлении функции прописываю для каждого слайдера отдельно(если, к примеру, их несколько на странице) - sliderLogic('.wrapper', 2, true, true, false, 1, 1000);
А мне хочется(да и удобнее так) сделать их отдельно опциями в самой функции, по типу как у слика того же
$('.slider-news').slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
arrows: false,
dots: true,
speed: 1000,
variableWidth: true,
чтоб можно было каждую опцию объявить, имя-значение, и для каждого слайдера прописывать.
Можете подсказать как это реализовать?
Ответы (1 шт):
Благодаря помощи тут, немного доработал слайдер. Оставлю тут, если вдруг кому нужен будет простой слайдер на чистом js, без доп. библиотек
function sliderLogic(options){
const sliderWpar = document.querySelector(options.sliderName);
const slider = sliderWpar.querySelector('.slider__line');
const dotsWrapper = sliderWpar.querySelector('.dots');
const buttonsWrapper = sliderWpar.querySelector('.buttons');
const slides = sliderWpar.querySelectorAll('.slider__item');
const slidesCount = slides.length;
const sliderBoxWidth = sliderWpar.querySelector('.slider').offsetWidth;
let slideWidth;
let countMovie = 0;
let dotCount = slidesCount - options.slideVisible+1;
let activeDot;
let autoScroll;
if(options.autoPlay){
autoScroll = setInterval(function(){
nextin(slideWidth);
}, options.autoPlayTime);
}
slider.style.cssText = `
position: relative;
left: 0;
display: flex;
align-items: center;
transition: all `+options.timeAnimation+`s ease-in;
`
slides.forEach( item => {
slideWidth = Math.round(sliderBoxWidth / options.slideVisible);
item.style.width = slideWidth + 'px';
});
function goSlide(n){
countMovie = countMovie - n;
if( countMovie < -( (slideWidth * slides.length) - (options.slideVisible * slideWidth) ) ){
countMovie = 0;
}
if( countMovie > 0 ){
countMovie = -(slideWidth * slides.length) - -(options.slideVisible * slideWidth);
}
dotsElems.forEach( elem => {
elem.classList.remove('active');
});
activeDot = countMovie / -slideWidth;
if( options.dots ){
dotsElems[activeDot].classList.add('active');
}
slider.style.left = countMovie + 'px';
}
function nextin(n){
goSlide(n);
}
function previous(n){
goSlide(-n);
}
if( options.dots ){
let dot = '';
for( let i = 0; i < dotCount; i++ ){
dot += '<span class="dots__item"></span>'
}
dotsWrapper.innerHTML = dot;
}
let dotsElems = sliderWpar.querySelectorAll('.dots__item');
dotsElems.forEach( (item, i) => {
if( countMovie == 0 ){
dotsElems[0].classList.add('active');
}
item.addEventListener('click', function(){
clearInterval(autoScroll);
dotsElems.forEach( elem => {
elem.classList.remove('active');
});
this.classList.add('active');
countMovie = 0 - (i * slideWidth);
slider.style.left = countMovie + 'px';
});
});
if(options.buttons){
let sliderClassName = sliderWpar.className;
const nextButton = document.createElement('button');
nextButton.classList.add(''+sliderClassName+'__next');
nextButton.innerText = 'next';
const prevButton = document.createElement('button');
prevButton.classList.add(''+sliderClassName+'__prev');
prevButton.innerText = 'prev';
buttonsWrapper.append(prevButton, nextButton);
nextButton.addEventListener('click', function() {
nextin(slideWidth);
clearInterval(autoScroll);
});
prevButton.addEventListener('click', () => {
previous(slideWidth);
clearInterval(autoScroll);
});
}
}
sliderLogic({
sliderName: '.wrapper',
slideVisible: 3,
dots: true,
buttons: false,
autoPlay: true,
timeAnimation: 1,
autoPlayTime: 2000
});
sliderLogic({
sliderName: '.wrapper-2',
slideVisible: 4,
dots: true,
buttons: true,
autoPlay: true,
timeAnimation: 1,
autoPlayTime: 2000
});
body{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper,
.wrapper-2{
width: 800px;
margin: 0 0 30px 0;
}
.slider{
width: 100%;
margin: 0 0 20px 0;
border: 1px solid;
overflow: hidden;
box-sizing: border-box;
}
.slider__item{
flex-shrink: 0;
padding: 5px;
box-sizing: border-box;
}
.slider__item img{
display: block;
width: 100%;
}
.dots{
margin: 30px 0;
}
.dots__item{
width: 10px;
height: 10px;
margin: 5px 7px;
padding: 0;
display: inline-block;
background: #BBB;
border-radius: 5px;
cursor: pointer;
}
.active{
background: #000 !important;
}
<div class="wrapper">
<div class="slider">
<div class="slider__line">
<div class="slider__item">
<img src="https://tes-game.ru/_nw/14/08884847.jpg" alt="">1
</div>
<div class="slider__item">
<img src="https://xage.ru/media/posts/2019/8/26/26-minutes-of-gameplay-dying-light-2-in-4k-trailer_BOLSTko.jpg" alt="">2
</div>
<div class="slider__item">
<img src="https://free4kwallpapers.com/uploads/originals/2020/05/02/game-art-wallpaper.jpg" alt="">3
</div>
<div class="slider__item">
<img src="https://images.hdqwalls.com/wallpapers/bthumb/resident-evil-2-2019-4k-5a.jpg" alt="">4
</div>
<div class="slider__item">
<img src="https://gamespot1.cbsistatic.com/uploads/screen_kubrick/1406/14063904/3477799-7716868968-far-c.jpg" alt="">5
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">6
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">7
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">8
</div>
</div>
</div>
<div class="dots"></div>
<div class="buttons"></div>
</div>
<div class="wrapper-2">
<div class="slider">
<div class="slider__line">
<div class="slider__item">
<img src="https://tes-game.ru/_nw/14/08884847.jpg" alt="">1
</div>
<div class="slider__item">
<img src="https://xage.ru/media/posts/2019/8/26/26-minutes-of-gameplay-dying-light-2-in-4k-trailer_BOLSTko.jpg" alt="">2
</div>
<div class="slider__item">
<img src="https://free4kwallpapers.com/uploads/originals/2020/05/02/game-art-wallpaper.jpg" alt="">3
</div>
<div class="slider__item">
<img src="https://images.hdqwalls.com/wallpapers/bthumb/resident-evil-2-2019-4k-5a.jpg" alt="">4
</div>
<div class="slider__item">
<img src="https://gamespot1.cbsistatic.com/uploads/screen_kubrick/1406/14063904/3477799-7716868968-far-c.jpg" alt="">5
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">6
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">7
</div>
<div class="slider__item">
<img src="https://www.gametube.sk/wp-content/uploads/2016/11/Screenshot-10.12.2016-17_53_06.jpg" alt="">8
</div>
</div>
</div>
<div class="dots"></div>
<div class="buttons"></div>
</div>