Как исправить слайдер чтобы он функционировал

Рейтинг: 0Ответов: 3Опубликовано: 20.02.2023

Сделал слайдер в 3 картинки, написал js, но переключается только с первой на вторую картинку и перестаёт работать. В чём проблема?

const slides = document.querySelectorAll('.slider-img');
const activeSlide = document.querySelector('.slider-img.active');

function changeSlide() {
  let nextSlide = activeSlide.nextElementSibling;
  if (!nextSlide) {
    nextSlide = slides[0];
  }
  activeSlide.classList.remove('active');
  nextSlide.classList.add('active');
}

setInterval(changeSlide, 3000);
.slider {
  display: flex;
  flex-direction: row;
  margin-top: 6rem;
  margin-left: 50rem
}

.slider img {
  display: none;
  object-fit: cover;
  height: 20rem;
  border-radius: 20%;
}

.slider img.active {
  display: block;
}
<section class="slider">
  <img src="imgs/img-rainbowcity.png" class="slider-img active">
  <img src="imgs/psico-img.webp" class="slider-img">
  <img src="imgs/psico2-img.webp" class="slider-img">
</section>

Ответы

▲ 1Принят

переменная activeSlide устанавливается один раз при запуске скрипта и не обновляется внутри функции changeSlide(), поэтому всегда будет ссылаться на один и тот же элемент. В результате, скрипт будет менять классы только у первого слайда, и никаких других слайдов не будет переключаться.

Для исправления этой проблемы нужно переместить определение переменной activeSlide внутрь функции changeSlide(), чтобы оно запрашивало активный слайд на каждой итерации цикла

const slides = document.querySelectorAll('.slider-img');

function changeSlide() {
  const activeSlide = document.querySelector('.slider-img.active');
  let nextSlide = activeSlide.nextElementSibling;
  if (!nextSlide) {
    nextSlide = slides[0];
  }
  activeSlide.classList.remove('active');
  nextSlide.classList.add('active');
}

setInterval(changeSlide, 3000);
.slider {
  display: flex;
  flex-direction: row;
  margin-top: 6rem;
  margin-left: 50rem
}

.slider img {
  display: none;
  object-fit: cover;
  height: 20rem;
  border-radius: 20%;
}

.slider img.active {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="slider">
  <img src="imgs/img-rainbowcity.png" class="slider-img active">
  <img src="imgs/psico-img.webp" class="slider-img">
  <img src="imgs/psico2-img.webp" class="slider-img">
</section>

▲ 0

У вас функция при каждом вызове одно и тоже выполняет, нет счетчика, нет перебора, поэтому ничего и не работает. Попробуйте такой вариант, посмотрите как работает изнутри, посмотрите на поведение во вкладке elements в devtools, поймите как работает и уже опитимизируете под себя.

const slides = document.querySelectorAll('.slider-img');
let counter = 0;

function changeSlide(i) {
  slides.forEach((slide) => {
    slide.style.display = 'none';
  });
  slides[i].style.display = 'block';
}

setInterval(() => {
  if (counter == slides.length - 1) {
    counter = 0;
  } else {
    counter++;
  }
  changeSlide(counter);
}, 1000);
▲ 0

В чём проблема?

Вот тебе вариант более короткий по тексту. И осторожнее с rem - это же от размера шрифта влияет.

Ты можешь просто не увидеть своих картинок. ;)

const slides = document.querySelectorAll('.slider-img');
let i = 0


function changeSlide() {
  slides[i].classList.remove('active');
  i = ++i % slides.length
  slides[i].classList.add('active');
}

setInterval(changeSlide, 1000);
html {
  font-size: 8px;
}

.slider {
  display: flex;
  width: 200px;
  height: 200px;
  flex-direction: row;
  margin-top: 6rem;
  margin-left: 50rem;
}

.slider img {
  display: none;
  object-fit: cover;
  height: 20rem;
  border-radius: 20%;
}

.slider img.active {
  display: block;
}
<section class="slider">
  <img src="https://w-dog.ru/wallpapers/5/18/352642460976053/koshka-vzglyad-fon.jpg" class="slider-img active">
  <img src="https://proprikol.ru/wp-content/uploads/2020/09/kartinki-milyh-zhivotnyh-52.jpg" class="slider-img">
  <img src="https://funart.pro/uploads/posts/2021-04/1618038701_46-p-oboi-kartinki-tigrov-49.jpg" class="slider-img">
</section>