Как реализовать автоматическую зацикленную карусель на JS

     let i = 1;
    for(let li of carousel.querySelectorAll('li')) {
      li.style.position = 'relative';
      li.insertAdjacentHTML('beforeend', `<span style="position:absolute;left:0;top:0">${i}</span>`);
      i++;
    }

    /* конфигурация */
    let width = 130; // ширина картинки
    let count = 3; // видимое количество изображений

    let list = carousel.querySelector('ul');
    let listElems = carousel.querySelectorAll('li');

    let position = 0; // положение ленты прокрутки

    carousel.querySelector('.prev').onclick = function() {
      // сдвиг влево
      position += width * count;
      // последнее передвижение влево может быть не на 3, а на 2 или 1 элемент
      position = Math.min(position, 0)
      list.style.marginLeft = position + 'px';
    };

    carousel.querySelector('.next').onclick = function() {
      // сдвиг вправо
      position -= width * count;
      // последнее передвижение вправо может быть не на 3, а на 2 или 1 элемент
      position = Math.max(position, -width * (listElems.length - count));
      list.style.marginLeft = position + 'px';
    };
body {
  padding: 10px;
}

.carousel {
  position: relative;
  width: 398px;
  padding: 10px 40px;
  border: 1px solid #CCC;
  border-radius: 15px;
  background: #eee;
}

.carousel img {
  width: 130px;
  height: 130px;
  /* делаем этот элемент блочным, чтобы убрать лишнее пространство вокруг картинок */
  display: block;
}

.arrow {
  position: absolute;
  top: 60px;
  padding: 0;
  background: #ddd;
  border-radius: 15px;
  border: 1px solid gray;
  font-size: 24px;
  line-height: 24px;
  color: #444;
  display: block;
}

.arrow:focus {
  outline: none;
}

.arrow:hover {
  background: #ccc;
  cursor: pointer;
}

.prev {
  left: 7px;
}

.next {
  right: 7px;
}

.gallery {
  width: 390px;
  overflow: hidden;
}

.gallery ul {
  height: 130px;
  width: 9999px;
  margin: 0;
  padding: 0;
  list-style: none;
  transition: margin-left 250ms;
  /* удаляем пустое пространство между элементами li, у которых установлен inline-block */
  /* http://davidwalsh.name/remove-whitespace-inline-block */
  font-size: 0;
}

.gallery li {
  display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <div id="carousel" class="carousel">
    <button class="arrow prev">⇦</button>
    <div class="gallery">
      <ul>
        <li><img src="https://ru.js.cx/carousel/1.png"></li>
        <li><img src="https://ru.js.cx/carousel/2.png"></li>
        <li><img src="https://ru.js.cx/carousel/3.png"></li>
        <li><img src="https://ru.js.cx/carousel/4.png"></li>
        <li><img src="https://ru.js.cx/carousel/5.png"></li>
        <li><img src="https://ru.js.cx/carousel/6.png"></li>
        <li><img src="https://ru.js.cx/carousel/7.png"></li>
        <li><img src="https://ru.js.cx/carousel/8.png"></li>
        <li><img src="https://ru.js.cx/carousel/9.png"></li>
        <li><img src="https://ru.js.cx/carousel/10.png"></li>
      </ul>
    </div>
    <button class="arrow next">⇨</button>
  </div>

</body>
</html>


Ответы (1 шт):

Автор решения: Dmitry Kulakov

Примерно так

       let i = 1;
for(let li of carousel.querySelectorAll('li')) {
  li.style.position = 'relative';
  li.insertAdjacentHTML('beforeend', `<span style="position:absolute;left:0;top:0">${i}</span>`);
  i++;
}

/* конфигурация */
let width = 130; // ширина картинки
let count = 3; // видимое количество изображений

let list = carousel.querySelector('ul');
let listElems = carousel.querySelectorAll('li');

let position = 0; // положение ленты прокрутки

carousel.querySelector('.prev').onclick = function() {
  // сдвиг влево
  if (Math.abs(position) === 0) {
    position = -((listElems.length * width) - width * count);
  } else {
    position += width * count;
  }
  // последнее передвижение влево может быть не на 3, а на 2 или 1 элемент
  position = Math.min(position, 0)
  list.style.marginLeft = position + 'px';
};

carousel.querySelector('.next').onclick = function() {
  // сдвиг вправо

  position -= width * count;
  if (Math.abs(position) === listElems.length * width) {
    position = 0;
  }
  // последнее передвижение вправо может быть не на 3, а на 2 или 1 элемент
  position = Math.max(position, -width * (listElems.length - count));
  list.style.marginLeft = position + 'px';
};
body {
  padding: 10px;
}

.carousel {
  position: relative;
  width: 398px;
  padding: 10px 40px;
  border: 1px solid #CCC;
  border-radius: 15px;
  background: #eee;
}

.carousel img {
  width: 130px;
  height: 130px;
  /* делаем этот элемент блочным, чтобы убрать лишнее пространство вокруг картинок */
  display: block;
}

.arrow {
  position: absolute;
  top: 60px;
  padding: 0;
  background: #ddd;
  border-radius: 15px;
  border: 1px solid gray;
  font-size: 24px;
  line-height: 24px;
  color: #444;
  display: block;
}

.arrow:focus {
  outline: none;
}

.arrow:hover {
  background: #ccc;
  cursor: pointer;
}

.prev {
  left: 7px;
}

.next {
  right: 7px;
}

.gallery {
  width: 390px;
  overflow: hidden;
}

.gallery ul {
  height: 130px;
  width: 9999px;
  margin: 0;
  padding: 0;
  list-style: none;
  transition: margin-left 250ms;
  /* удаляем пустое пространство между элементами li, у которых установлен inline-block */
  /* http://davidwalsh.name/remove-whitespace-inline-block */
  font-size: 0;
}

.gallery li {
  display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <div id="carousel" class="carousel">
    <button class="arrow prev">⇦</button>
    <div class="gallery">
      <ul>
        <li><img src="https://ru.js.cx/carousel/1.png"></li>
        <li><img src="https://ru.js.cx/carousel/2.png"></li>
        <li><img src="https://ru.js.cx/carousel/3.png"></li>
        <li><img src="https://ru.js.cx/carousel/4.png"></li>
        <li><img src="https://ru.js.cx/carousel/5.png"></li>
        <li><img src="https://ru.js.cx/carousel/6.png"></li>
        <li><img src="https://ru.js.cx/carousel/7.png"></li>
        <li><img src="https://ru.js.cx/carousel/8.png"></li>
        <li><img src="https://ru.js.cx/carousel/9.png"></li>
        <li><img src="https://ru.js.cx/carousel/10.png"></li>
      </ul>
    </div>
    <button class="arrow next">⇨</button>
  </div>

</body>
</html>

→ Ссылка