при достижении последнего слайда изменять translateX в положительную сторону
Создаю слайдер, с автоплеем, который при достижении определенного условия будет идти в обратную сторону.
Проблема заключается в том что когда он доходит до определенной границы, он начинает дергаться на этой границе, прибавлять один пиксель и сразу же убавлять.
// ---------------sliider----------------------
const prev = document.querySelector('.slider__btn_prev'),
next = document.querySelector('.slider__btn_next'),
slider = document.querySelector('.slider_top'),
slidesWrapper = document.querySelector('.slider__wrapper'),
slidesField = document.querySelector('.slider__field');
let width = 0;
// slidesField.style.width = 100 * slides.length + '%';
slidesWrapper.style.overflow = 'hidden';
slider.style.position = 'relative';
function moveSliderRight() {
if (width > -100 ) {
width -= 1;
slidesField.style.transform = `translateX(${width}px)`;
} else {
width += 1;
slidesField.style.transform = `translateX(${width}px)`;
}
//console.log(width);
}
let sliderInterval = setInterval(moveSliderRight, 40);
slider.addEventListener('mouseenter', () => {
clearInterval(sliderInterval);
slidesField.style.transition = 'all 0.5s ease 0s';
});
slider.addEventListener('mouseleave', () => {
sliderInterval = setInterval(moveSliderRight, 40);
slidesField.style.transition = 'all 0.1s ease 0s';
});
next.addEventListener('click', () => {
width -= 400;
slidesField.style.transform = `translateX(${width}px)`;
});
prev.addEventListener('click', () => {
width += 400;
slidesField.style.transform = `translateX(${width + 400}px)`;
});
.slider_top {
position: relative;
}
.slider__wrapper {
width: 100%;
overflow: hidden;
}
.slider__field {
display: flex;
list-style-type: none;
transition: all 0.1s ease 0s;
gap: 20px;
}
.slider__slide {
height: 400px;
}
img {
height: 100%;
}
<section class="sliders">
<div class="slider_top">
<div class="slider__wrapper">
<ul class="slider__field">
<li class="slider__slide">
<a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
<img src="https://i.imgur.com/fsyrScY.jpg" alt="">
</a>
</li>
<li class="slider__slide">
<a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
<img src="https://i.imgur.com/fsyrScY.jpg" alt="">
</a>
</li>
<li class="slider__slide">
<a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
<img src="https://i.imgur.com/fsyrScY.jpg" alt="">
</a>
</li>
<li class="slider__slide">
<a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
<img src="https://i.imgur.com/fsyrScY.jpg" alt="">
</a>
</li>
<li class="slider__slide">
<a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
<img src="https://i.imgur.com/fsyrScY.jpg" alt="">
</a>
</li>
</ul>
</div>
<div class="slider__btns">
<button class="slider__btn slider__btn_prev">left</button>
<button class="slider__btn slider__btn_next">right</button>
</div>
</div>
</section>
Ответы (1 шт):
Автор решения: Павел Рыбакин
→ Ссылка
SetTimeout - плохое решение. Анимация из-за него становится рваной и это влияет на производительность.
Я переписал код и заменил SetTimeout на requestAnimationFrame:
window.addEventListener('DOMContentLoaded', () => {
// ---------------sliider----------------------
const prev = document.querySelector('.slider__btn_prev'),
next = document.querySelector('.slider__btn_next'),
slider = document.querySelector('.slider_top'),
slidesWrapper = document.querySelector('.slider__wrapper'),
slidesField = document.querySelector('.slider__field'),
slides = document.querySelectorAll('.slider__slide');
let width = 0,
widthRace = 0;
//получаем ширину дорожки слайдера
function getWidthRace() {
slides.forEach(slide => {
const widthItem = slide.clientWidth;
widthRace -= widthItem;
});
widthRace += slidesWrapper.clientWidth;
}
getWidthRace();
slidesWrapper.style.overflow = 'hidden';
slider.style.position = 'relative';
//запускаем движение слайдера влево
function moveLeft() {
width += 1;
slidesField.style.transform = `translateX(${width}px)`;
if (width < 0) {
requestAnimationFrame(moveLeft);
} else {
moveSlider();
}
}
//запускаем движение слайдера вправо
function moveRight() {
width -= 1;
slidesField.style.transform = `translateX(${width}px)`;
if (width > widthRace) {
requestAnimationFrame(moveRight);
} else {
moveSlider();
}
}
function moveSlider() {
if (width > widthRace) {
moveRight();
} else if (width < 0) {
moveLeft();
}
}
moveSlider();
next.addEventListener('click', () => {
width += widthRace / 2;
slidesField.style.transform = `translateX(${width}px)`;
});
prev.addEventListener('click', () => {
width += -widthRace / 2;
slidesField.style.transform = `translateX(${width}px)`;
});
});
.slider_top {
position: relative;
}
.slider__wrapper {
width: 100%;
overflow: hidden;
}
.slider__field {
display: flex;
list-style-type: none;
transition: all 0.5s ease 0s;
padding: 0;
}
.slider__slide {
height: 400px;
padding-right: 20px;
}
.slider__slide:last-child {
padding-right: 0;
}
img {
height: 100%;
}
<section class="sliders">
<div class="slider_top">
<div class="slider__wrapper">
<ul class="slider__field">
<li class="slider__slide">
<img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042492_01.jpg" alt="">
</li>
<li class="slider__slide">
<img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042585_06.jpg" alt="">
</li>
<li class="slider__slide">
<img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042485_04.jpg" alt="">
</li>
<li class="slider__slide">
<img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042660_10.jpg" alt="">
</li>
</ul>
</div>
<div class="slider__btns">
<button class="slider__btn slider__btn_prev">left</button>
<button class="slider__btn slider__btn_next">right</button>
</div>
</div>
</section>