Как сделать бесконечный скролл, с автоматической подстановкой начальных элементов скролла в конец

Есть список с элементами от 1 до 10. Этот список скроллится вниз. Нужно чтобы при достижении конца скролла, а именно элемента 10, список не заканчивался, а после 10 элемента добавлялся опять элемент 1, 2, 3 и тд, тем самым чтобы скролл был бесконечным.

Вот код: https://codepen.io/talisman4ik123/pen/zYEqpvQ

HTML:

<body>
  <div class="box">
    <ul class="list">
      <li class="item">1</li>
      <li class="item">2</li>
      <li class="item">3</li>
      <li class="item">4</li>
      <li class="item">5</li>
      <li class="item">6</li>
      <li class="item">7</li>
      <li class="item">8</li>
      <li class="item">9</li>
      <li class="item">10</li>
    </ul>
  </div>
</body>

CSS

.list {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100px;
  background-color: gold;
  height: 100px;
  overflow-y: scroll;
  padding: 10px;
  font-size: 20px;
    &::-webkit-scrollbar {
        width: 0;
    }
}

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

Автор решения: UModeL

Циклическая прокрутка пунктов списка

Для разметки и размеров приведённых в вопросе, решения довольно простые:

Событие "wheel"

Отслеживаем направление вращения колеса мыши и, на основании этого, переставляем первый/последний элемент в конец/начало списка:

const list = document.querySelector('.list');
list.addEventListener('wheel', function(ev) {
  let items = this.querySelectorAll('.item');
  if (ev.wheelDelta > 0) {
    this.prepend(items[items.length - 1]);
  } else {
    this.append(items[0]);
  }
});
.list {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100px; width: 100px;
  margin: 0; padding: 10px;
  overflow-y: scroll;
  font-size: 20px;
  background-color: gold;
}
.list::-webkit-scrollbar {
  width: 0;
}
<ul class="list">
  <li class="item">1</li>
  <li class="item">2</li>
  <li class="item">3</li>
  <li class="item">4</li>
  <li class="item">5</li>
  <li class="item">6</li>
  <li class="item">7</li>
  <li class="item">8</li>
  <li class="item">9</li>
  <li class="item">10</li>
</ul>

Недостаток этого метода в том, что он срабатывает только на прокрутку с помощью колёсика мыши, а для прокрутки с помощь стрелок на клавиатуре или на сенсорном экране необходимы дополнительные обработчики.

Событие "scroll"

Этот способ лишён недостатков предыдущего, так как использует стандартное и более универсальное событие. Небольшая запутанность кода возникает из-за реализации определения направления прокрутки:

const list = document.querySelector('.list');
list.scrollTop = 1;
list.addEventListener('scroll', function(ev) {
  let items = this.querySelectorAll('.item');
  if (parseInt(this.scrollTop) == 0) {
    this.scrollTop = items[items.length - 1].clientHeight;
    this.prepend(items[items.length - 1]);
    this.scrollTop = 1;
  } else if (this.scrollTop > this.scrollHeight - this.clientHeight - 1) {
    this.append(items[0]);
  }
  return false;
});
.list {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100px; width: 100px;
  margin: 0; padding: 10px;
  overflow-y: scroll;
  font-size: 20px;
  background-color: gold;
}
.list::-webkit-scrollbar {
  width: 0;
}
<ul class="list">
  <li class="item">1</li>
  <li class="item">2</li>
  <li class="item">3</li>
  <li class="item">4</li>
  <li class="item">5</li>
  <li class="item">6</li>
  <li class="item">7</li>
  <li class="item">8</li>
  <li class="item">9</li>
  <li class="item">10</li>
</ul>

Минус данного подхода - немного дерганный и неравномерный скроллинг, в виду особенностей родного поведения разных браузеров.

→ Ссылка