<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>무한 스크롤!</title>
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Title -->
<h1>언스플래쉬 api를 활용한 무한 스크롤</h1>
<!-- Loader -->
<div class="loader" id="loader">
<img src="loader.svg" alt="Loading">
</div>
<!-- Image Container -->
<div class="image-container" id="image-container"></div>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>
@import url("https://fonts.googleapis.com/css?family=Bebas+Neue&display=swap");
html {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Bebas Neue, sans-serif;
background: whitesmoke;
}
h1 {
text-align: center;
margin-top: 25px;
margin-bottom: 15px;
font-size: 40px;
letter-spacing: 5px;
}
/* Loader */
.loader {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(255, 255, 255, 0.8);
}
.loader img {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Image Container */
.image-container {
margin: 10px 30%;
}
.image-container img {
width: 100%;
margin-top: 5px;
}
/* Media Query: Large Smartphone Vertical */
@media screen and (max-width: 600px) {
h1 {
font-size: 20px;
}
.image-container {
margin: 10px;
}
}
const imageContainer = document.getElementById('image-container');
const loader = document.getElementById('loader');
//이미지와 로딩 가져옴.
let ready = false; //이미지를 가져올때 쓰는 불리언값.
let imagesLoaded = 0;
//이미지 로딩확인.
let totalImages = 0;
let photosArray = []; //사진이 들어갈 배열.
//unsplash API 사용.
const count = 30;
const apiKey = 'jFgS8tteGD425f4oZfygQVaVnD6gt6GucN2yyz3xFek';
const apiUrl = `https://api.unsplash.com/photos/random?client_id=${apiKey}&count=${count}`;
// 모든 이미지가 로드 됐는지 확인.
function imageLoaded() {
imagesLoaded++;
if (imagesLoaded === totalImages) {
//전부 로딩이 되었다면.
ready = true;
loader.hidden = true;
//로딩애니메이션 숨기기.
}
}
// DOM 요소에 setattribute 사용.
function setAttributes(element, attributes) {
//변경 요소와 변경사항을 받음.
for (const key in attributes) {
element.setAttribute(key, attributes[key]);
}
}
//사진과 링크가 담긴 요소를 생성해 문서에 추가한다.
function displayPhotos(){
imagesLoaded =0;
totalImages = photosArray.length;
//사진 배열의 모든 사진에 대해.
photosArray.forEach((photo) =>{
const item = document.createElement('a');
setAttributes(item,{
href: photo.links.html,
target: '_blank',
});//앵커 태그 생성하고 연결되는 문서를 사진의 문서로 함.
//사진 이미지가 들어갈 이미지 태그 생성.
const img = document.createElement('img');
setAttributes(img,{
src: photo.urls.regular,
alt: photo.alt_description,
title: photo.alt_description,
});// 사진의 주소, 설명, 제목을 생성.
//이미지가 다 로딩 됐는지를 이벤트로 체크.
img.addEventListener('load',imageLoaded);
//img태그 안에 a태그를 넣고, 그 둘을 모두 imageContainer요소 안에 집어넣기.
item.appendChild(img);
//링크를 이미지의 자식화.
imageContainer.appendChild(item);
});
}
//사이트에서 이미지 가져오기.
async function getPhotos(){
try{
const response = await fetch(apiUrl);
photosArray = await response.json();
// 사진 배열에 바로 저장.
displayPhotos();
//사진 출력을 실행.
} catch(error){
}
}
//스크롤이 화면 아래에 가까이 있으면 더 많은 사진을 로드하기.
window.addEventListener('scroll', () =>{
if(window.innerHeight + window.scrollY >= document.body.offsetHeight - 1000 && ready){
//1000px은 일반적으로 문서의 최댓값. 즉 그걸 뺀다는건, 순수하게 가져온 이미지들의 전체 길이의 합을 계산한다는 것. 그리고 이거 이상이라는건 이미지들이 다 나가서 더이상 출력될게 없다는 걸 뜻하니 이미지를 더 로드해야 한다.
ready = false;
getPhotos();//따라서 이미지를 더 가져옴.
}
});
getPhotos();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.