JSFiddle - React, Tailwind, and code Playground
HTML
<div id="root" class="container">
<div id="loader" class="loader">
<img class="loader-img" src='https://i.imgur.com/YwRCROv.gif'>
</div>
</div>
CSS
.container {
height: 300px;
width: 60%;
border: 1px solid #d3d3d3;
overflow: auto;
margin: 40px;
background-color: #F6F7F9;
border-radius: 5px;
}
.item {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
background-color: #dbdbdb;
margin: 10px;
float: left;
border-radius: 5px;
box-shadow: 1px 5px 8px 0px rgba(47,57,71,0.06);
}
.loader {
display: flex;
width: 100%;
height: 100px;
align-items: center;
justify-content: center;
}
.loader-img {
width: 80px;
height: 35px;
}
JavaScript 1.7
function getContent(offset, num) {
let arr = [];
for (var i = offset; i < offset + num; i++) {
arr.push(i);
}
return new Promise((resolve) => {
setTimeout(() => {
resolve(arr);
}, Math.random() * 2000);
});
}
/**
Returns a generator which returns the items as a stream
*/
async function* items(batchSize) {
let offset = 0;
while (true) {
yield await getContent(offset, batchSize);
offset += batchSize;
}
}
async function* events(el, name, condition) {
let resolve;
el.addEventListener(name, e => {
if (condition(e)) {
resolve(e);
}
});
while (true) {
yield await new Promise(_resolve => resolve = _resolve);
}
}
const container = document.getElementById('root');
const loader = document.getElementById('loader');
async function init() {
let eventIterator = events(container, 'scroll', () =>container.scrollHeight <= container.scrollTop + container.clientHeight);
for await (const page of items(50)) {
append(page);
debugger;
await eventIterator.next();
}
}
function append(items) {
let dom = items.map(item => `<div class=item>${item}</div>`).join('');
container.insertAdjacentHTML('beforeend', dom);
container.append(loader);
}
init();