맡은 부분 : 상세 페이지 영화 리뷰 작성 기능 구현
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Comment</title>
<link rel="stylesheet" href="detail.css" />
<script type="module" src="comment.js"></script>
</head>
<body>
<main>
<div class="review__title">
<h3>Review</h3>
<span>12233</span>
</div>
<section class="comment-make__box">
<img
class="user-image"
src="https://static.vecteezy.com/system/resources/thumbnails/005/276/776/small/logo-icon-person-on-white-background-free-vector.jpg"
/>
<form class="comment-write__box">
<div class="id-password__box">
<input id="username" type="text" required placeholder="Username" />
<input
id="password"
type="password"
required
placeholder="Password"
/>
</div>
<div class="comment-write">
<textarea
id="write"
placeholder="감상평을 남겨주세요."
required
></textarea>
<button class="wrtie-btn">
<i class="fa-solid fa-pen-to-square fa-lg"></i>
</button>
</div>
</form>
</section>
<ul class="comment__wrapper"></ul>
</main>
<script
src="https://kit.fontawesome.com/748fe0d700.js"
crossorigin="anonymous"
></script>
</body>
</html>
먼저 html 요소들을 가져와서 변수를 지정해줬다.
const commentForm = document.querySelector(".comment-write__box");
const usernameInput = document.getElementById("username");
const passwordInput = document.getElementById("password");
const commentInput = document.getElementById("write");
form에 submit이벤트를 실행시켰을 때, 로컬스토리지에 값을 가져오고, 저장하고, 댓글을 그리는 것까지 handleSubmitForm함수 안에서 실행시켜준다.
const handleSubmitForm = (event) => {
event.preventDefault();
// 입력된 이름, 댓글 내용 가져오기
const username = usernameInput.value;
const password = passwordInput.value;
const comment = commentInput.value;
//값 비우기, 변수의 값에는 영향 x
usernameInput.value = "";
passwordInput.value = "";
commentInput.value = "";
//로컬 스토리지에 username이랑 password 저장
// 값을 담을 새로운 객체 생성
let newComment = {
user: username,
password: password,
review: comment,
};
// 1. 로컬스토리지에서 가져온다.
const commentsArr = getComments();
// 새로운 배열에 객체 값 넣어주기
// 2. 로컬스토리지에 있는 데이터에 추가한다.
commentsArr.unshift(newComment); //push는 배열 뒤부터 추가, unshift는 앞에서부터 추가
saveComments(commentsArr); //commentsArr배열을 추가해서 저장
generateComment(newComment);
};
commentForm.addEventListener("submit", handleSubmitForm);
코멘트를 로컬스토리지에 저장해줄 때는, 객체나 배열을 브라우저에서 읽을 수 있도록 JSON.stringify()
메서드를 사용해서 JSON 데이터 형태로 저장해준다.
//여기서 comments는 인자로 사용
const saveComments = (comments) => {
localStorage.setItem("comments", JSON.stringify(comments));
};
로컬스토리지에서 다시 데이터를 가져올 때는, 자바스크립트가 읽을 수 있도록 JSON.parse()
메서드로 JSON 형식으로 파싱하여 댓글 배열로 반환한다. 저장된 값이 없다면 빈 배열을 return해주도록 한다. 그리고 데이터를 담은 새로운 배열은 handleSubmitForm 함수와 generateComment 함수에서 사용할 수 있다.
// 로컬 스토리지에서 댓글 배열 가져오기
const getComments = () => {
const savedComments = localStorage.getItem("comments");
if (savedComments) {
return JSON.parse(savedComments); //다시 배열로 바꿔주기
} else {
return [];
}
};
댓글을 만들 때는 우선 html을 그려줄 요소를 가져온 뒤 내용을 초기화 해준다. getComments()로 만들었던 배열을 함수 안에서 사용할 수 있도록 commentDrawn 변수에 다시 할당시켜주고, forEach을 사용해 이 배열을 순회하면서 innerHTML로 댓글을 그려준다.
const generateComment = () => {
const commentBox = document.querySelector(".comment__wrapper");
commentBox.innerHTML = "";
let commentDrawn = getComments();
//commentsDrawn를 순회하면서 댓글 그리기
commentDrawn.forEach((element) => {
commentBox.innerHTML += `
<li class="comment__box">
<img
class="user-image"
src="https://static.vecteezy.com/system/resources/thumbnails/005/276/776/small/logo-icon-person-on-white-background-free-vector.jpg"
/>
<section class="comment">
<h4>${element.user}</h4>
<p>${element.review}</p>
</section>
<div class="rate">
<i class="fa-regular fa-thumbs-up fa-lg"></i>
<span>55</span>
</div>
</li>`;
});
};
마지막으로 페이지가 로드될 때, 작성된 댓글을 보여줄 수 있도록 해준다.
// 4. 페이지가 로드될 때 기존 댓글 불러오기
window.onload = function () {
generateComment();
};