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();
};