JSFiddle - React, Tailwind, and code Playground

by Prathameshsb

HTML

<div class="card-container"></div>

CSS

.card-container{
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
}

.card {
  border: 1px solid black;
  width: 50%;
  padding: 10px;
  background-color: #f2f2f2;
  border-radius: 5px;
  transform: translateX(100px);
  transition: 150ms;
  opacity: 0;
}

.card.show{
  transform: translateX(0);
  opacity: 1; 
}

JavaScript

const cardContainer = document.querySelector('.card-container');
    const dataArray = Array.from({ length: 30000 }, (_, i) => `Card ${i + 1}`);
    let cardIndex = 0;
    const batchSize = 10;

    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('show');
        } else {
          entry.target.classList.remove('show');
        }
      });
    }, {
      threshold: 1
    });

    const lastCardObserver = new IntersectionObserver(entries => {
      const lastCard = entries[0];
      if (!lastCard.isIntersecting) return;
      loadNewCards();
      lastCardObserver.unobserve(lastCard.target);
      lastCardObserver.observe(document.querySelector('.card:last-child'));
    }, {});

    function loadNewCards() {
      if (cardIndex >= dataArray.length) return;

      for (let i = 0; i < batchSize && cardIndex < dataArray.length; i++) {
        const card = document.createElement('div');
        card.textContent = dataArray[cardIndex];
        card.classList.add('card');
        observer.observe(card);
        cardContainer.append(card);
        cardIndex++;
      }
    }

    // Initial load
    loadNewCards();
    lastCardObserver.observe(document.querySelector('.card:last-child'));