JavaScript infinite scroll with intersection observer I built a simple infinite scroll using the intersection observer API, would love some feedback on ways to improve my JavaScript and make it more maintainable and reusable, and feedback according to best JavaScript practices.
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;title&gt;Infinite Scroll&lt;/title&gt;
    &lt;style&gt;
      body {
        font-family: sans-serif;
        font-size: 16px;
      }
      .container {
        display: flex;
        flex-direction: column;
        align-items: center;
        max-width: 520px;
        margin: 0 auto;
      }
      img {
        width: 100%;
        height: 100%;
        margin: 1rem 2rem;
      }
      #load-more {
        padding: 1rem 2rem;
        margin: 2;
        background-color: darkcyan;
        color: white;
        border-radius: 1rem;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div id=&quot;infinite-scroll-imgs-container&quot;&gt;&lt;/div&gt;
      &lt;div id=&quot;load-more&quot;&gt;Loading more content...&lt;/div&gt;
    &lt;/div&gt;
    &lt;script&gt;
      const loadMore = document.querySelector(&quot;#load-more&quot;);
      const observer = new IntersectionObserver(handleIntersect, { threshold: 1 });
      const imgsContainer = document.querySelector(&quot;#infinite-scroll-imgs-container&quot;);

      observer.observe(loadMore)

      function randomInteger() {
        return Math.floor(Math.random() * 1000000);
      }

      function imgGenerator(images) {
        const imgs = [];
        for (let i = 0; i &lt; images; i += 1) {
          const img = document.createElement(&quot;img&quot;);
          img.src = `http://api.adorable.io/avatars/${randomInteger()}`;
          img.classList.add('infinite-scroll-img')
          imgs.push(img);
        }
        return imgs;
      }

      function appendImages(container, images) {
        container.append(...imgGenerator(images));
      }

      function handleIntersect(entries, observer) {
        entries.forEach((entry) =&gt; {
          if (entry.isIntersecting) {
            appendImages(imgsContainer, 5);
          }
        });
      }

      appendImages(imgsContainer, 5);
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
I think that container and images are being repeated unecessarly.

When you call imgGenerator in appendImages, you already know that you want an array of images.
You can use Array.from:

the first argument will be an array-like object, that is, an object that is accessed by index and with a length propertie(which is identified as images on our javascript)
the second argument will be the mapFunction(which will
be imgGenerator), a function that will be called for every
item of the array

Doing this, on imgGenerator you avoid to make an instance of an array(imgs), a push into it and a for loop every time you want this array, although, you will not need to pass images as parameter again

the container is always imgsContainer, so, in the appendImages you already know where to append


function imgGenerator() {
  const img = document.createElement("img");
  img.src = `http://api.adorable.io/avatars/${randomInteger()}`;
  img.classList.add('infinite-scroll-img');
  return img;
}

function appendImages(images) {
  imgsContainer.append(
    ...Array.from({ length: images }, imgGenerator)
  );
}

function handleIntersect(entries) {
  entries.forEach(entry =&gt; {
    if (entry.isIntersecting) {
      appendImages(5);
    }
  });
}

appendImages(5);