<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>무한 스크롤</title>
</head>
<body>
<h1>내 블로그</h1>
<div class="mainContainer">
<div class="filter-container">
<input type="text" id="filter" class="filter" placeholder="Filter posts...">
</div>
<div class="posts-container" id="postContainer">
</div>
<div class="loadingContainer show" id="loadingContainer">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
*{
box-sizing: border-box;
}
body{
height: 100vh;
margin: 0;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
background-color: rgb(146, 173, 235);
}
h1{
text-align: center;
margin-bottom: 0;
}
.mainContainer{
margin: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.filter-container{
width: 70%;
margin-top: 20px;
}
.filter-container input{
width: 100%;
padding: 15px;
border: 1px solid #fff;
background-color: #fff;
font-size: 16px;
border-radius: 16px;
}
.filter-container input:focus{
outline: 0;
}
.posts-container{
width: 70%;
}
.posts{
border: none;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
background-color: rgb(143, 143, 201);
border-radius: 10px;
margin: 60px 0;
padding: 30px;
display: flex;
justify-content: center;
align-content: center;
position: relative;
}
.post-info{
margin-left: 10px;
}
.post-title{
margin-bottom: 10px;
font-weight: bold;
font-size: 24px;
}
.number{
width: 50px;
height:50px;
border-radius: 50%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
color: rgb(146, 173, 235);
position: absolute;
top: -30;
left: -20;
}
.post-body{
font-size: 16px;
}
.loadingContainer{
width: 150px;
height: 50px;
display: none;
justify-content: center;
align-items: center;
}
.loadingContainer.show{
display: flex;
}
.circle{
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #fff;
margin: 5px;
animation: transformY 0.7s infinite;
}
.circle:nth-child(2){
animation-delay: 0.1s;
}
.circle:nth-child(3){
animation-delay: 0.2s;
}
@keyframes transformY{
0%, 100%{
transform: translateY(0);
}
50%{
transform: translateY(-10px);
}
}
const filter = document.getElementById("filter");
const postContainer = document.getElementById("postContainer");
const loadingIcon = document.getElementById("loadingContainer");
let limit = 5;
let page = 1;
// 데이터 요청해오기
const getRandomPost = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`
);
const data = await res.json();
console.log(data);
addToDOMData(data);
};
// 데이터 브라우저에 띄우기
const addToDOMData = (data) => {
data.forEach((item) => {
const post = document.createElement("div");
post.classList.add("posts");
post.innerHTML = `<div class="number">${item.id}</div>
<div class="post-info">
<div class="post-title">${item.title}
</div>
<div class="post-body">${item.body}
</div>
</div>`;
postContainer.appendChild(post);
});
};
//스크롤 이벤트
document.addEventListener("scroll", (e) => {
const { clientHeight, scrollTop, scrollHeight } = e.target.scrollingElement;
if (clientHeight + scrollTop >= scrollHeight) {
setTimeout(() => {
page++;
getRandomPost();
}, 500);
}
});
//필터링 이벤트
const filterPost = (e) => {
const words = e.target.value;
const posts = document.querySelectorAll(".posts");
posts.forEach(post => {
const title = post.querySelector('.post-title').innerText;
const body = post.querySelector('.post-body').innerText;
if(title.indexOf(words) > -1 || body.indexOf(words) > -1){
post.style.display = 'flex';
} else{
post.style.display = 'none';
}
})
}
getRandomPost();
filter.addEventListener('input', filterPost);
scrollTop 은 글의 시작 위치부터 현재 화면에 보이는 부분 전까지의 길이이다.
scrollTop 을 통해 지금까지 스크롤을 해온 길이를 구할 수 있다.
scrollHeight 는 페이지 전체 글의 길이 이다.
clientHeight 는 현재 화면에서 보이는 높이이다.
그러므로 지금까지 스크롤 해온 길이와 현재 높이를 합했을때, 페이지 전체 글의 길이보다 길다면
스크롤 이벤트가 발생하게 된다.
document.addEventListener("scroll", (e) => {
const { clientHeight, scrollTop, scrollHeight } = e.target.scrollingElement;
if (clientHeight + scrollTop >= scrollHeight) {
....
}
});
document.scrollingElement는 문서를 스크롤하는 Element에 대한 참조값을 반환한다.