목차
1. 디자인 시안 확인
board-list.html
게시글이 없는 경우 (비로그인시), 게시글이 는 경우(로그인시)
2. (사전 기반 지식) 자바스크립트의 if문 조건식의 평가 방식
if (조건) {
// 조건이 true일 때 실행되는 코드
}
자바스크립트에서 if 문 안에 들어가는 조건식은 Boolean 값으로 평가됩니다.
즉, 조건식이 true로 평가되면 코드 블록이 실행되고, false로 평가되면 실행되지 않습니다.
- 자바 스크립트 "truthy"와 "falsy”
다음은 자바스크립트에서 거짓(false)으로 평가되는 "falsy" 값
false: Boolean 값 false
0: 숫자 0
"": 빈 문자열 (길이가 0인 문자열)
null: 값이 없음을 나타내는 값
undefined: 정의되지 않은 상태를 나타내는 값
NaN: 숫자가 아님을 나타내는 값 (Not-a-Number)
if (0) {
// 이 코드는 실행되지 않습니다. (0은 falsy 값이므로)
}
위에 나열된 "falsy" 값들을 제외한 모든 값은 "truthy" 값으로 간주된다. 즉, if 문에서 참(true)으로 평가된다.
true
1, -1, 또는 다른 모든 숫자
"hello"와 같은 길이가 1 이상인 문자열
객체 ({}, [] 등)
if ("둘리") {
// 이 코드는 실행됩니다. ("둘리"는 truthy 값이므로)
}
if (1) {
// 이 코드는 실행됩니다. ("둘리"는 truthy 값이므로)
}
if (-1) {
// 이 코드는 실행됩니다. ("둘리"는 truthy 값이므로)
}
3. 코드
board-list.html
<!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="stylesheet" href="../css/common.css" />
<link rel="stylesheet" href="../css/header.css" />
<link rel="stylesheet" href="../css/border.css" />
</head>
<body>
<header>
<nav class="nav-container">
<div class="nav-item">
<span class="menu-link" id="board">게시판</span>
</div>
<div class="nav-item" id="authLinks">
<span class="menu-link" id="signIn">로그인</span>
<span class="menu-link" id="signUp">회원가입</span>
</div>
</nav>
</header>
<main class="content-wrapper">
<section class="title-box">
<h1>게시글 상세보기 by JS</h1>
</section>
<div class="content-box">
<div class="board-box">
<div class="head">
<div class="head-1">번호</div>
<div class="head-2">제목</div>
<div class="head-3">작성자</div>
<div class="head-4">작성일</div>
<div class="head-5">조회수</div>
</div>
<div class="board-content-box">
</div>
<!-- 페이징 영역 -->
<div class="botton-box">
<div class="page-box">
<span class="left">◀</span>
<div class="num-box">
<span class="num">1</span>
</div>
<span class="right">▶</span>
</div>
<div class="write-button-box">
<button type="button" class="btn">글쓰기</button>
</div>
</div>
</div>
</div>
</main>
<script src="../js/header.js"></script>
<script src="../js/boardList.js"></script>
</body>
</html>
boardList.css
.content-box {
display: flex;
flex-direction: column;
width: 100%;
max-width: 1000px;
}
.board-box {
display: flex;
flex-direction: column;
}
.head,
.board {
border-bottom: 1px solid black;
display: flex;
justify-content: space-between;
padding: 10px;
align-items: center;
}
/* 제목, content 공간 영역 맞추기 */
.head-1,
.board-1 {
/* flex 속성 (고정 너비) */
flex: 0 0 80px;
}
.head-2,
.board-2 {
/* 가변 너비 */
flex: 1;
text-align: left;
padding-left: 10px;
padding-right: 10px;
}
.head-3,
.board-3,
.head-4,
.board-4,
.head-5,
.board-5 {
/* 고정 너비 */
flex: 0 0 100px;
}
/* 하단 영역 */
.button-box {
display: flex;
flex-direction: column;
margin-top: 20px;
}
.page-box {
display: flex;
justify-content: center;
padding: 20px;
}
.write-button-box {
display: flex;
justify-content: flex-end;
}
boardList.js
// 샘플 데이터 입력
const sampleBoardList = [
{
id: 1,
title: "첫번째 게시글",
content: "첫번째 게시글의 내용 입니다.",
username: "홍길동",
today: "2024.08.25",
count: 5,
},
{
id: 2,
title: "두번째 게시글",
content: "두번째 게시글의 내용 입니다.",
username: "이몽룡",
today: "2024.08.25",
count: 5,
},
{
id: 3,
title: "세번째 게시글",
content: "세번째 게시글의 내용 입니다.",
username: "성춘향",
today: "2024.08.25",
count: 14,
},
{
id: 4,
title: "네번째 게시글",
content: "네번째 게시글의 내용 입니다.",
username: "변학도",
today: "2024.08.25",
count: 21,
},
{
id: 5,
title: "다섯번째 게시글",
content: "다섯번째 게시글의 내용 입니다.",
username: "심청",
today: "2024.08.25",
count: 51,
},
];
localStorage.setItem("boardList", JSON.stringify(sampleBoardList));
document.addEventListener("DOMContentLoaded", () => {
// DOM 접근
const boardContainer = document.querySelector(".board-content-box"); // 컨텐트를 넣을 Element 선택
const writeButton = document.querySelector(".btn"); // 글쓰기 버튼 Element 선택
const paginationContainer = document.querySelector(".num-box");
// 로컬 스토리지에서 게시글 목록 가져오기
const storedBoardList = JSON.parse(localStorage.getItem("boardList"));
if (storedBoardList) {
storedBoardList.reverse();
}
// 페이징 처리 필요한 변수
let currentPage = 0;
const limit = 2; // 한 페이지당 게시글 수
loadPosts(currentPage);
// 게시글 목록을 내림차순으로 정렬하기
// 게시글을 로드 하는 함수
function loadPosts(page) {
const offset = page * limit;
const end =
offset + limit > storedBoardList.length
? storedBoardList.length
: offset + limit;
let postElements = ""; // 게시글 HTML 요소를 저장할 변수
// 방어적 코드 작성
if (storedBoardList != null && storedBoardList.length > 0) {
// 반복문을 사용()
for (let i = offset; i < end; i++) {
postElements += `<div class="board" data-id=${storedBoardList[i].id}>
<div class="board-1">${i + 1}</div>
<div class="board-2">${storedBoardList[i].title}</div>
<div class="board-3">${storedBoardList[i].username}</div>
<div class="board-4">${storedBoardList[i].today}</div>
<div class="board-5">${storedBoardList[i].count}</div>
</div>`;
}
boardContainer.innerHTML = postElements;
// 페이지 네이션 생성
createPagination(storedBoardList, page);
} else {
// 게시글이 없는 경우 메세지 표시
boardContainer.innerHTML =
'<div class="no-list" style="text-align: center; margin-top: 20px">조회된 게시글이 없습니다.</div>';
}
}
// 페이지 네이션 생성 함수 선언
function createPagination(boardList, currentPage) {
// 전체 게시글 수, 한 페이지당 보여질 게시글 수
const totalPosts = boardList.length; // 전체 게시글 수
const totalPages = Math.ceil(totalPosts / limit); // 전체 페이지 수
// 페이지 번호 HTML 저장할 변수
let paginationHTML = "";
for (let i = 0; i < totalPages; i++) {
paginationHTML += `<span class="num" data-page="${i}">${i + 1}</span>`;
}
paginationContainer.innerHTML = paginationHTML;
// 생성된 페이지 번호의 요소 접근 (동적 할당)
const pageNumbers = document.querySelectorAll('.num');
// 현재 페이지 번호에 스타일 적용
pageNumbers[currentPage].style.backgroundColor = 'grey';
pageNumbers[currentPage].style.fontWeight = 600;
pageNumbers.forEach((pageNumber) => {
pageNumber.addEventListener('click', (event) => {
// console.log('event',event);
// console.log('event.target',event.target);
// console.log('event.target.dataset',event.target.dataset);
// console.log('event.target.dataset.page',event.target.dataset.page);
// 해당하는 번호를 가지고 와서 다시 렌더링
const targetPageNumber = parseInt(event.target.dataset.page);
loadPosts(targetPageNumber);
});
});
// 글쓰기 버튼 눌렀을 경우 -> 글쓰기 페이지 이동 처리
writeButton.onclick = function(){
location.href = "board-write.html";
}
// 해당 row 게시글을 눌렀을 경우 -> 상세보기 화면 이동 처리
}
});
4. data-* 속성 및 dataset 개념
1. data-* 속성
data-* 속성은 HTML5에서 제공하는 사용자 정의 데이터 속성이다. 이 속성을 사용하면 HTML 요소에 데이터를 저장할 수 있으며, 이 데이터는 JavaScript로 쉽게 접근할 수 있다.
- data-* 속성의 이름은 반드시 data-로 시작하고, 그 뒤에 사용자 정의 키를 붙일 수 있다. 예를 들어, data-id, data-user, data-index 등이 가능하다.
<div data-id="123" data-name="둘리1"></div>
2. dataset 객체
dataset 객체는 JavaScript에서 HTML 요소의 data-* 속성에 접근할 수 있도록 해주는 특수한 객체이다. dataset 객체를 사용하면 data-*로 시작하는 모든 속성에 접근할 수 있으며, 이를 통해 데이터 값을 가져오거나 변경할 수 있다.
const myDiv = document.getElementById('myDiv');
// data-id 속성에 접근
console.log(myDiv.dataset.id); // 출력: 123
// data-name 속성에 접근
console.log(myDiv.dataset.name); // 출력: 둘리
// data-name 속성의 값을 변경
myDiv.dataset.name = "고길동";
console.log(myDiv.dataset.name); // 출력: 고길동
'JS > JavaScript 게시판 만들기' 카테고리의 다른 글
8. JavaScript boardDetail.js 상세보기 화면 만들기 (1) | 2024.08.29 |
---|---|
7. JavaScript boardWrite.js 글쓰기 기능 만들기 (0) | 2024.08.27 |
5. JavaScript 로그인 기능 만들기 (1) | 2024.08.22 |
4. JavaScript 회원 가입 만들기 (0) | 2024.08.21 |
2. 실행환경 구축 (VS CODE) (0) | 2024.08.21 |