2021-10-20 Infinite Scroll Part 4
by Ttt Yyy
HTML
<div id='container'>
<!-- <div class="list-item">
<img class="list-item__image" src="https://" />
<span class="list-item__label">Label</span>
</div> -->
</div>
CSS
#container {
/* position: relative; */
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
}
.list-item {
align-items: center;
display: flex;
position: absolute;
}
.list-item__image {
height: 50px;
width: 50px;
}
.list-item__label {
margin-left: 12px;
}
JavaScript
let container = document.getElementById("container");
let currentTopPosition = 0;
const ROW_HEIGHT = 50;
const reapedNodes = [];
let currentIndex = 0;
function createRow(url, label) {
let row;
if (reapedNodes.length > 0) {
row = reapedNodes.shift();
} else {
row = document.createElement("div");
row.className = "list-item";
row.innerHTML = `<img src=${url} class='list-item__image'>
<span class="list-item__label">${label}</span>`;
// given container now has position: relative, row has position: absolute
}
row.style.top = `${currentTopPosition}px`;
currentTopPosition += ROW_HEIGHT;
return row;
}
// assuming rows looks like: [{url: 'https://' label: 'Test Label'}]
const addRowsBulk = (rows, amount) => {
const fragment = document.createDocumentFragment();
for (let i = currentIndex; i < amount; i++) {
const { url, label } = rows[i];
const row = createRow(url, label);
fragment.appendChild(row);
currentIndex++;
}
container.appendChild(fragment);
};
function removeUnseenToReaped() {
for (let i = 0; i < container.children.length; i++) {
const row = container.children[i];
const topPosition = parseInt(row.style.top);
// if already passed row
if (container.scrollTop >= topPosition + ROW_HEIGHT) {
reapedNodes.push(row);
let newRow = rows[currentIndex++];
createRow(newRow.url, newRow.label);
}
}
}
container.addEventListener("scroll", function () {
if (container.scrollHeight - container.scrollTop === container.clientHeight) {
removeUnseenToReaped();
}
});
const rows = [
{
url: "https://img.pokemondb.net/sprites/omega-ruby-alpha-sapphire/dex/normal/zapdos.png",
label: "Zapdos",
},
{
url: "https://img.pokemondb.net/sprites/omega-ruby-alpha-sapphire/dex/normal/moltres.png",
label: "Moltres",
},
{
url: "https://img.pokemondb.net/sprites/omega-ruby-alpha-sapphire/dex/normal/articuno.png",
label: "Articuno",
},
{
url:...