html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>포토 앨범: TS 비동기 작업</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="app">
<div id="photo-container">
<!--
하위 요소로 외부 API에서 이미지를 첨부
: class 속성(photo-item)
-->
</div>
<div id="button-container">
<button id="prev-button">Previous</button>
<button id="next-button">Next</button>
</div>
</div>
<script src="./main.js"></script>
</body>
</html>
css
body {
background-color: #f4f4f9;
color: #333;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#app {
background-color: #fff;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 600px;
/* app 내부에서 크기가 커질 경우 생기는 스크롤 제거 */
overflow: hidden;
border-radius: 10px;
text-align: center;
}
#photo-container {
display: grid;
/* 컨테이너 내부에 요소가 2열의 공간이 같은 비율로 할당 */
grid-template-columns: repeat(2, 1fr);
gap: 15px;
padding: 20px;
}
#prev-button, #next-button {
background-color: #007bff;
color: #fff;
border: none;
padding: 10px 20px;
margin: 10px;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
#prev-button:hover, #next-button:hover {
background-color: #0056b3;
}
#button-container {
padding: 10px;
display: flex;
justify-content: space-between;
}
.photo-item {
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
background-color: #fff;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
text-align: center;
}
.photo-item img {
max-width: 100%;
height: auto;
border-radius: 5px;
margin-bottom: 10px;
}
.photo-item p {
font-weight: bold;
color: #555;
margin: 0;
}
js
/*
! 외부 API를 사용하는 비동기 작업 프로젝트
- jsonplaceholder의 photos 데이터를 사용
>> URL을 통한 데이터 요청 시
>> URL경로?키=쌍의 형태로 옵션 전달 가능
# 요구 사항 정리
- 각 페이지에 photos 데이터의 사진을 4개씩 첨부
(50 === (4 * 12) + 2)
- 각 사진의 이름 (title)은 사진 아래 작성
- 페이지 간의 이동은 버튼(Previous, Next)으로 이동
- async/await를 사용하여 작성
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
// 현재 페이지 번호를 추적하는 변수 선언 (1로 초기화)
var currentPage = 1;
// 한 페이지에 표시할 사진의 수
var photoPerPage = 4;
//? 지정된 페이지의 사진들을 비동기적으로 불러오는 함수 선언
function fetchPhotos(page) {
return __awaiter(this, void 0, void 0, function () {
var response, photos, renderPhotos_1, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
case 1:
response = _a.sent();
if (!response.ok) {
throw new Error('데이터를 가져오지 못했습니다.');
}
return [4 /*yield*/, response.json()];
case 2:
photos = _a.sent();
renderPhotos_1 = photos.splice((page - 1) * photoPerPage, photoPerPage);
return [2 /*return*/, renderPhotos_1];
case 3:
error_1 = _a.sent();
console.error('Failed');
return [2 /*return*/, []];
case 4: return [2 /*return*/];
}
});
});
}
//? 사진을 페이지에 렌더링하는 함수
// : 4개씩 나누어진 사진 배열을 매개변수로 받아옴
function renderPhotos(photos) {
// 사진을 표시할 HTML 요소
var container = document.getElementById('photo-container');
container.innerHTML = '';
// 각 사진에 대한 HTML 요소 생성
photos.forEach(function (photo) {
var photoElement = document.createElement('div');
photoElement.className = 'photo-item';
photoElement.innerHTML = "\n <img src='".concat(photo.thumbnailUrl, "' alt='").concat(photo.title, "' />\n <p>").concat(photo.title, "</p>\n ");
container.appendChild(photoElement);
});
}
//! 버튼 이벤트 등록
// 이전 버튼 이벤트
document.getElementById('prev-button').addEventListener('click', function () {
// 현재 페이지가 1보다 크면 이전 페이지로 이동 (로직 실행)
if (currentPage > 1) {
currentPage--;
updatePhotos();
}
});
// 다음 버튼 이벤트
document.getElementById('next-button').addEventListener('click', function () {
// 다음 페이지로 이동
currentPage++;
updatePhotos();
});
// 다음 버튼 이벤트
//? 전체 프로젝트 실행 (사진 불러오기)
function updatePhotos() {
return __awaiter(this, void 0, void 0, function () {
var photos;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetchPhotos(currentPage)];
case 1:
photos = _a.sent();
// 4개의 사진을 렌더링하는 함수 호출
renderPhotos(photos);
return [2 /*return*/];
}
});
});
}
updatePhotos();
'프로그래밍 예제' 카테고리의 다른 글
java 프로그래밍 예제(간단한 도서 관리 프로그램) (0) | 2024.09.20 |
---|---|
HTML, CSS, JS 활용 예제(간단한 todo list02, 모듈화) (0) | 2024.08.09 |
HTML, CSS, JS 활용 예제(간단한 todo list) (0) | 2024.08.08 |