feat: initial commit
This commit is contained in:
commit
6731fe212c
|
@ -0,0 +1,2 @@
|
||||||
|
infinite scrolling
|
||||||
|
https://webdesign.tutsplus.com/how-to-implement-infinite-scrolling-with-javascript--cms-37055t
|
|
@ -0,0 +1,27 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="styles.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- cards are added by JavaScript so it starts empty -->
|
||||||
|
<div id="card-container"></div>
|
||||||
|
|
||||||
|
<!-- loader displays an animation before adding the next batch of cards -->
|
||||||
|
<div id="loader">
|
||||||
|
<div class="skeleton-card"></div>
|
||||||
|
<div class="skeleton-card"></div>
|
||||||
|
<div class="skeleton-card"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- card actions shows the card count and card total (we probably do not need this) -->
|
||||||
|
<div id="card-actions">
|
||||||
|
<span>Showing
|
||||||
|
<span id="card-count"></span> of
|
||||||
|
<span id="card-total"></span> cards
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,90 @@
|
||||||
|
// first, let's get all the elements we'll need from our DOM
|
||||||
|
const cardContainer = document.getElementById("card-container");
|
||||||
|
const cardCountElem = document.getElementById("card-count");
|
||||||
|
const cardTotalElem = document.getElementById("card-total");
|
||||||
|
const loader = document.getElementById("loader");
|
||||||
|
|
||||||
|
// we'll need a value for the max numaer of cards to be added to the page
|
||||||
|
const cardLimit = 99;
|
||||||
|
// then we'll define a variable for how many cards we want to increase the
|
||||||
|
// page by
|
||||||
|
const cardIncrease = 9;
|
||||||
|
// how many times can we increase the content until we reach the max limit?
|
||||||
|
const pageCount = Math.ceil(cardLimit / cardIncrease);
|
||||||
|
// and define a value to determine which page we're on
|
||||||
|
let currentPage = 1;
|
||||||
|
|
||||||
|
cardTotalElem.innerHTML = cardLimit;
|
||||||
|
|
||||||
|
|
||||||
|
function getRandomColor() {
|
||||||
|
const h = Math.floor(Math.random() * 360);
|
||||||
|
return `hsl(${h}deg, 90%, 85%)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createCard(idx) {
|
||||||
|
const card = document.createElement("div");
|
||||||
|
card.className = "card";
|
||||||
|
card.innerHTML = idx;
|
||||||
|
card.style.backgroundColor = getRandomColor();
|
||||||
|
cardContainer.appendChild(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addCards(pageIdx) {
|
||||||
|
currentPage = pageIdx;
|
||||||
|
|
||||||
|
const startRange = (pageIdx - 1) * cardIncrease;
|
||||||
|
const endRange = currentPage == pageCount
|
||||||
|
? cardLimit
|
||||||
|
: pageIdx * cardIncrease;
|
||||||
|
|
||||||
|
cardCountElem.innerHTML = endRange;
|
||||||
|
|
||||||
|
for (let i = startRange + 1; i <= endRange; i++) {
|
||||||
|
createCard(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleInfiniteScroll() {
|
||||||
|
throttle(() => {
|
||||||
|
const endOfPage = window.innerHeight + window.pageYOffset >= document.body.offsetHeight;
|
||||||
|
|
||||||
|
if (endOfPage) {
|
||||||
|
addCards(currentPage + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPage === pageCount) {
|
||||||
|
removeInfiniteScroll();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var throttleTimer;
|
||||||
|
function throttle(callback, time) {
|
||||||
|
if (throttleTimer) return;
|
||||||
|
|
||||||
|
throttleTimer = true;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
callback();
|
||||||
|
throttleTimer = false;
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function removeInfiniteScroll() {
|
||||||
|
loader.remove();
|
||||||
|
window.removeEventListener("scroll", handleInfiniteScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
addCards(currentPage);
|
||||||
|
window.addEventListener("scroll", handleInfiniteScroll);
|
||||||
|
|
||||||
|
// TODO: define the limit of the content to be loaded on the page
|
||||||
|
// TODO: detect when the user has reached the end of the content container
|
||||||
|
// TODO: load more content once the end of the container has been reached
|
||||||
|
// TODO: if there's no more content to be loaded, stop the infinite scroll
|
|
@ -0,0 +1,62 @@
|
||||||
|
#card-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
height: 55vh;
|
||||||
|
width: calc((100% / 3) - 16px);
|
||||||
|
margin: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 200ms ease-in-out;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-actions {
|
||||||
|
margin: 8px;
|
||||||
|
padding: 16px 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loader {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-card {
|
||||||
|
height: 55vh;
|
||||||
|
width: calc((100% / 3) - 16px);
|
||||||
|
margin: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 200ms ease-in-out;
|
||||||
|
position: relative;
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-card::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0));
|
||||||
|
animation: load is infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes load {
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (prefers-reduced-motion: reduce) {
|
||||||
|
}
|
Loading…
Reference in New Issue