[WIL 2023.06.11] 내배캠 4주차
📝 Situation(상황): 이번주 목표
지난주 개인과제로 만들었던 영화검색 사이트를 develop
영화별 상세 페이지와 상세페이지 내 댓글 기능을 필수로 하여 팀으로 사이트 완성하기
👀 Task(임무): situation 중 문제들
그 중 나는 local storage를 이용하여 댓글 기능을 만드는 역할을 맡았다.
댓글의 CRUD 구현하기와 댓글창 UI를 깔끔하게 만드는데에 목표를 두었다.
🔍 Action(접근방법): 해결시도
먼저 폼태그 안에 인풋창을 두어 제출란을 만들었다.
// 코멘트 표시
function displayComments()
// 코멘트 HTML 생성
function createCommentHTML(comment, index)
// 새 코멘트 저장
function saveComment(event)
// 코멘트 수정
function editComment(index)
// 코멘트 삭제
function deleteComment(index)
5개의 함수를 두어 댓글을 생성, 수정, 삭제하게 했으나,
각 페이지마다 모두 같은 댓글이 보이는 문제가 발생하여 영화 데이터의 아이디별로 구분하여 댓글을 저장 할 수 있게 수정했다.
수정하면서 3개의 함수가 더 추가됨
function getCommentsForMovie(movieId)
function setCommentsForMovie(movieId, comments)
function getMovieIdFromURL()
그리고 댓글이 많아지면 스크롤을 한참 내려야 해서 상단이동 버튼이 있었으면 좋겠다 싶어 addEventListener를 이용해 산단이동 버튼 추가. 계속 버튼이 노출되어 있는것 보단 일정구간부터 표시되는게 보기 좋아보여서 조건을 붙여주었다.
if (scrollPosition > 200) {
topBtn.style.display = 'block';
} else {
topBtn.style.display = 'none';
}
기능 구현 후 댓글창을 보기좋게 css 수정을 하여 마무리 했으나
여전히 헷갈리는 flex와 grid....왜 이렇게 마음처럼 안따라주는지.. 꽤나 애를 먹었다.
그래도 여차저차 완성...!
📃 Result(결과): action 후 성과
완성한 전체코드
const commentForm = document.getElementById('commentForm');
const commentList = document.getElementById('commentList');
const movieId = getMovieIdFromURL(); // URL에서 영화 식별자를 가져오는 함수
commentForm.addEventListener('submit', saveComment);
displayComments();
// 코멘트 표시
function displayComments() {
const comments = getCommentsForMovie(movieId);
commentList.innerHTML = comments.length
? comments
.map((comment, index) => createCommentHTML(comment, index))
.join('')
: '저장된 댓글이 없습니다.';
}
// 코멘트 HTML 생성
function createCommentHTML(comment, index) {
return `
<div class="writtenComment">
<b>${comment.username}</b><p>${comment.comment}</p>
<div class="btn">
<button id="edit" onclick="editComment(${index})"><img src="../img/edit.png" alt="" /></button>
<button id="delete" onclick="deleteComment(${index})"><img src="../img/delete.png" alt="" /></button>
</div>
</div>
`;
}
// 새 코멘트 저장
function saveComment(event) {
event.preventDefault();
const username = document.getElementById('username').value;
const comment = document.getElementById('comment').value;
const password = document.getElementById('password').value;
const comments = getCommentsForMovie(movieId);
comments.push({ username, comment, password });
setCommentsForMovie(movieId, comments);
commentForm.reset();
displayComments();
}
// 코멘트 수정
function editComment(index) {
const comments = getCommentsForMovie(movieId);
const comment = comments[index];
const password = prompt('비밀번호를 입력하세요:');
if (password === comment.password) {
const updatedComment = prompt('수정할 댓글을 입력하세요:', comment.comment);
if (updatedComment !== null) {
comment.comment = updatedComment;
setCommentsForMovie(movieId, comments);
displayComments();
}
} else {
alert('비밀번호가 일치하지 않습니다.');
}
}
// 코멘트 삭제
function deleteComment(index) {
const comments = getCommentsForMovie(movieId);
const comment = comments[index];
const password = prompt('비밀번호를 입력하세요:');
if (password === comment.password) {
comments.splice(index, 1);
setCommentsForMovie(movieId, comments);
displayComments();
} else {
alert('비밀번호가 일치하지 않습니다.');
}
}
// 영화 식별자를 기반으로 해당 영화의 댓글을 가져옴
function getCommentsForMovie(movieId) {
const commentsJSON = localStorage.getItem(`comments_${movieId}`);
return commentsJSON ? JSON.parse(commentsJSON) : [];
}
// 영화 식별자를 기반으로 해당 영화의 댓글을 설정
function setCommentsForMovie(movieId, comments) {
localStorage.setItem(`comments_${movieId}`, JSON.stringify(comments));
}
// 현재 페이지의 URL에서 영화 식별자를 추출
function getMovieIdFromURL() {
const url = window.location.href;
const urlParts = url.split('?');
const movieId = urlParts[urlParts.length - 1];
return movieId;
}
// 버튼 클릭 시 맨 위로 이동
const commentBox = document.querySelector('.commentBox');
const topBtn = commentBox.querySelector('.moveTopBtn');
topBtn.addEventListener('click', () => {
commentBox.scrollTo({ top: 0, behavior: 'smooth' });
});
// 버튼 초기에 숨기기
topBtn.style.display = 'none';
// 스크롤 이벤트 핸들러
commentBox.addEventListener('scroll', () => {
const scrollPosition = commentBox.scrollTop;
// 버튼 보이기/숨기기 결정
if (scrollPosition > 200) {
topBtn.style.display = 'block';
} else {
topBtn.style.display = 'none';
}
});
애를 먹었던 css
📓 Point(정리): 이번주 요약
바닐라 자바스크립트로 local storage를 이용해 댓글 CRUD 기능 구현
& 댓글창 CSS
처음부터 계획해서 한번에 코드를 짜지않고 중간중간 계속 추가하려니
나의 능력으로 많이 후달렸지만 어째저째 기한 내에 완성은 되엇다.
하지만 역시 비밀번호 확인창과 댓글 수정란이 promt로 적용하는 바람에 알럿창으로 뜨는 것은 맘에 들지 않는다.
이것도 수정을 했어야 하는데 아쉽다...