<!DOCTYPE html>
<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();
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.