InfinteScroll

by Kondal Durgam

HTML

<div class="container">
	<h1>Infinite Scroll</h1>	
	<div class="element-list"></div>
</div>

CSS

.container {
    margin: 0 auto;
    max-width: 50em;
    padding: 1em;
  }
  
  .element-list__item {
    background-color: #eee;
    float: left;
    height: 15em;
    max-width: 50%;
    opacity: .75;
    -webkit-transform: scale(0.8);
            transform: scale(0.8);
    transition: opacity 0.2s, -webkit-transform 0.2s;
    transition: opacity 0.2s, transform 0.2s;
    transition: opacity 0.2s, transform 0.2s, -webkit-transform 0.2s;
    width: 15em;
  }
  .element-list__item:hover {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
  
  .element-list__item__image {
    display: block;
    height: auto;
    margin: 0;
    opacity: 1;
    transition: opacity 0.2s;
    width: 100%;
  }
  
  .element-list__item__loader {
    opacity: 0;
  }

JavaScript

function getDocumentHeight() {
    const body = document.body;
    const html = document.documentElement;

    return Math.max(
        body.scrollHeight, body.offsetHeight,
        html.clientHeight, html.scrollHeight, html.offsetHeight
    );
};

function getScrollTop() {
    return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
}

function generateImageSourceUrl() {
    const hash = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    return `http://api.adorable.io/avatars/250/${hash}`;
}

function getElementImage() {
    const cssImageClass = 'element-list__item__image';
    const cssImageLoadingClass = `${cssImageClass}--loading`;
	
    const image = new Image;
    image.className = `${cssImageClass} ${cssImageLoadingClass}`;
    image.src = generateImageSourceUrl();
    image.onload = function () {
        setTimeout(() => image.classList.remove(cssImageLoadingClass),5000)
    };

    return image;
}

function getElement() {
    const elementImage = getElementImage();
    const element = document.createElement('div');
    element.className = 'element-list__item';
    element.appendChild(elementImage);
    return element;
}

function loadNextBatch(batchSize = 9) {
    while (batchSize--) {
			  const element = getElement();
        elementList.appendChild(element);
    }
}

const elementList = document.querySelector('.element-list');

// Load the first batch of elements
loadNextBatch();

// Load more batches when scorlling to the end
window.onscroll = function () {
    if (getScrollTop() < getDocumentHeight() - window.innerHeight) return;
    loadNextBatch();
};