JSFiddle - React, Tailwind, and code Playground
HTML
<div class="context">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="boundary"></div>
</div>
CSS
.item {
width: 300px;
height: 200px;
border: 1px solid gray;
margin-bottom: 10px;
background-color: lightgray;
}
JavaScript
function template(num) {
return `
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div id="boundary-${num}" class="boundary"></div>
`;
}
class InfiniteScroll {
constructor(context) {
this.context = context;
this.boundaryList = null;
this.boundary = null;
this.scrollFlag = false;
this.num = 2;
}
renderItems() {
if (!this.scrollFlag) {
this.scrollFlag = true;
this.boundaryList = this.context.querySelectorAll('.boundary');
this.boundary = this.boundaryList[this.boundaryList.length - 1];
if (this.boundary) {
this.scrollFlag = false;
this.boundary.insertAdjacentHTML('afterend', template(this.num));
this.num++;
}
}
}
searchElement() {
this.boundaryList.forEach(el => {
return this.isVisible(el);
});
}
isVisible() {
let el = this.boundary;
let top = el.offsetTop;
let left = el.offsetLeft;
let width = el.offsetWidth;
let height = el.offsetHeight;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
if (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
) return el;
}
}
const $context = document.querySelector('.context');
const infiniteScroll = new InfiniteScroll($context);
window.addEventListener('scroll', () => {
const contentHeight = $context.offsetHeight;
const yOffset = window.pageYOffset;
const window_height = window.innerHeight;
const y = yOffset + window_height;
if (y >= contentHeight) {
infiniteScroll.renderItems();
}
console.log(infiniteScroll.searchElement());
});