infinite scroll using intersection observer
youtube
by ygongdev
HTML
<ul id="infinite-scroll-list">
<p id="loader">
isLoading
</p>
</ul>
CSS
.item {
height: 200px;
background-color: gray;
margin-bottom: 20px;
font-size: 24px;
text-align: center;
}
#loader {
position: fixed;
top: 50%;
left: 50%;
transform : translate(-50% -50%);
font-size: 24px;
}
.show {
display: block;
}
.hide {
display: none;
}
JavaScript
const fetchPagingAPI = function(paging) {
// paging.count
// paging.start
const newData = new Array(paging.count).fill().map((_, idx) => paging.start + idx);
return new Promise((resolve) => {
setTimeout(() => resolve(newData), 1000);
});
} //
class InfiniteScroll {
get infiniteScrollElement() {
return document.querySelector(this.infiniteScrollId);
}
get loaderElement() {
return document.querySelector(this.loaderId)
}
constructor(infiniteScrollId, loaderId, api, { count }) {
this.infiniteScrollId = infiniteScrollId;
this.loaderId = loaderId;
this.fetchAPI = api;
this._start = 0;
this._count = count;
this._observedElement = undefined;
this._observer = new IntersectionObserver(this._paginateCallback.bind(this));
this._showLoader(true);
this._paginate().finally(() => {
this._showLoader(false);
});
}
_paginateCallback(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
// show a loader
this._showLoader(true);
this._paginate().finally(() => {
this._showLoader(false);
});
}
})
}
_showLoader(show) {
if (show) {
this.loaderElement.classList.add('show');
this.loaderElement.classList.remove('hide');
} else {
this.loaderElement.classList.remove('show');
this.loaderElement.classList.add('hide');
}
}
async _paginate() {
const paging = {
start: this._start,
count: this._count
}
const data = await this.fetchAPI(paging);
this._start += this._count;
this._addToDOM(data);
}
_addToDOM(data) {
const fragment = document.createDocumentFragment();
if (this._observedElement) {
this._observer.unobserve(this._observedElement);
}
for (let i = 0; i< data.length; i++) {
const li = document.createElement('li');
li.textContent = data[i] + 1;
li.classList.add('item');
...