Sobes.tech
Middle

Имплементи виртуалӣ скролл: рӯйхати дарозии паёмҳо (10 000 унсур), танҳо унсурҳои намоён дар дохили контейнер бо баландии 300px, бо баландии сатр 30px бояд рендер карда шаванд.

sobes.tech AI

Ҷавоб аз AI

Для реализации виртуального скролла с 10 000 элементами и фиксированной высотой контейнера 300px (высота строки 30px) можно использовать следующий подход:

  1. Вычислить количество видимых элементов: 300px / 30px = 10 элементов.
  2. Отслеживать текущий скролл контейнера и вычислять индекс первого видимого элемента: startIndex = Math.floor(scrollTop / 30).
  3. Рендерить только элементы с индексами от startIndex до startIndex + visibleCount + buffer (buffer — небольшой запас, например 2 элемента, чтобы избежать мерцания).
  4. Для сохранения общей высоты списка использовать пустой блок с высотой totalHeight = 10000 * 30 = 300000px.
  5. Сдвигать контейнер с видимыми элементами вниз на startIndex * 30px с помощью CSS transform или padding-top.

Пример на React:

function VirtualList({ items }) {
  const containerHeight = 300;
  const rowHeight = 30;
  const totalCount = items.length;
  const visibleCount = Math.ceil(containerHeight / rowHeight);
  const buffer = 2;

  const [scrollTop, setScrollTop] = React.useState(0);

  const startIndex = Math.floor(scrollTop / rowHeight);
  const endIndex = Math.min(startIndex + visibleCount + buffer, totalCount);

  const visibleItems = items.slice(startIndex, endIndex);

  const onScroll = (e) => {
    setScrollTop(e.currentTarget.scrollTop);
  };

  return (
    <div style={{ height: containerHeight, overflowY: 'auto' }} onScroll={onScroll}>
      <div style={{ height: totalCount * rowHeight, position: 'relative' }}>
        <div style={{
          position: 'absolute',
          top: startIndex * rowHeight,
          left: 0,
          right: 0
        }}>
          {visibleItems.map((item, index) => (
            <div key={startIndex + index} style={{ height: rowHeight }}>
              {item}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Такой подход позволяет эффективно рендерить только видимые элементы, экономя ресурсы браузера.