인스타그램 클론 프로젝트 회고

DongHee Kim·2021년 8월 16일
4

Project

목록 보기
4/7
post-thumbnail

(페이지에 담긴 계정들엔 사실 사심이 듬뿍 담겨있다.)

Project Overview

HTML, CSS로 홈페이지만 보고 뼈대를 잡고, 일부 기능까지 Javascript로 직접 구현해본 인스타그램 클론 프로젝트
HTML, CSS적인 부분은 뭐랄까.. 약간의 하드코딩이 곁들여진..^^ 탓에 꽤나 품이 들었지만 Javasciprt로 여러 동적인 기능을 구현하며 배운 바가 많았다.
이 포스팅은 새롭게 구현해본 Javascript 기능을 위주로 기록해 볼 예정

작업 기간

총 4일 : 8/10(화) - 8/13(금)

기술 스택

  • HTML
  • CSS
  • Javascript

구현해낸 기능

(* HTML, CSS적인 요소는 제외하고 작성)

로그인 페이지

  • ID, PW validation

메인 페이지

  • 댓글 입력
  • 댓글 좋아요/취소
  • 댓글 삭제

기억하고 싶은 것들

bottom-up 레이아웃

이건 CSS적인 요소이지만 큰 깨달음을 얻었기에 작성해본다.
부끄럽지만 처음에 메인 페이지 레이아웃을 짤 때 부모 요소의 width, height값을 모두 고정값으로 준 top-down방식을 사용했다.
그러다보니 댓글 입력 후 등록시 계속해서 댓글이 늘어나며 height가 유동적으로 늘어나야하는데, 그 기능 구현이 어려워 중간에 수정해야했다.

기억하자. 레이아웃을 구성할 땐 자식요소의 높이에 따라 부모요소의 높이가 유동적으로 결정되는 bottom-up 방식으로 구성하자!
세부 element의 값에 필요시 고정값을 주고 (이 프로젝트의 경우엔 width값 고정이 필요했다), 부모 element는 padding 등으로 위치만 잡아두자.

로그인 페이지

ID, PW validation

id : '@' 포함 / pw : 5글자 이상 일 때 로그인 버튼 활성화 기능을 구현했다.

Javascript 코드

'use strict;'
const loginInfo = document.querySelector(".loginBox");
const thisIsBtn = document.querySelector('.loginBtn');

//기본적으로 버튼은 사용불가한 상태
thisIsBtn.disabled= true;
thisIsBtn.style.backgroundColor = "rgba(var(--d69,0,149,246),.3)"; 

//input을 포함하는 form에 keyup 이벤트 추가
loginInfo.addEventListener('keyup',function(){

  const thisIsID = document.querySelector('.id').value;
  const thisIsPW = document.querySelector('.password').value;

  //삼항 연산자를 활용해 조건 충족시 버튼 활성화/색상을 바꿔주었다.
((!thisIsID.includes("@")===false) && (thisIsPW.length >= 5)) ? (
  thisIsBtn.disabled = false,
  thisIsBtn.style.backgroundColor = "rgba(var(--d69,0,149,246),1)"
  ) : (
  thisIsBtn.disabled= true,
  thisIsBtn.style.backgroundColor = "rgba(var(--d69,0,149,246),.3)",
  thisIsBtn.style.cursor = "Pointer"
  )
})

메인페이지

Javascript 코드

서로 연관성이 많기에, 우선 페이지의 전체적인 코드부터!

'use strict;'
const commentBtn = document.querySelector(".feeds-comment_btn");
const feedsText = document.querySelector(".feeds-text");
const commentText = document.querySelector(".feeds-comment_box");

// 함수 선언 : 댓글 생성
function plusComment() {
  const newComment = document.createElement('li');
  newComment.innerHTML = `<span><span class="accountName">donghee</span> ${commentText.value}</span>` 
                       + `<div><span class="heart"><i class="far fa-heart"></i></span>
                       <span class="delete"><i class="far fa-trash-alt"></i></span></div>`;
  feedsText.appendChild(newComment);
  commentText.value = null;
  likeComment(newComment);
  deleteComment(newComment);
}

// 함수 선언 : 댓글 삭제 함수
function deleteComment(newComment) {
  const deleteBtn = newComment.querySelector(".delete");
  deleteBtn.addEventListener("click",() => newComment.remove());
  deleteBtn.style.cursor = "Pointer";
}

// 함수 선언 : 댓글 좋아요/취소 함수
function likeComment(newComment) {
  const likeBtn = newComment.querySelector(".heart");
  likeBtn.style.cursor = "Pointer";
  likeBtn.addEventListener("click",function() {
    event.target.className = event.target.className === "far fa-heart" ? "fas fa-heart" : "far fa-heart";
})}

// 이벤트 추가
commentBtn.addEventListener("click",plusComment)

commentText.addEventListener('keypress', function (e) {
  if (e.key === 'Enter') {
    plusComment()
    }
})

댓글 입력 기능

게시 버튼과 엔터 키를 입력하면 새로운 댓글이 li로 생성되도록 했다.
새로운 댓글에 적용되는 댓글 좋아요/취소 기능, 삭제 기능 함수도 모두 댓글 입력 함수 안에 포함시켰다.

// 함수 선언 : 댓글 생성
function plusComment() {
  const newComment = document.createElement('li');
  newComment.innerHTML = `<span><span class="accountName">donghee</span> ${commentText.value}</span>` 
                       + `<div><span class="heart"><i class="far fa-heart"></i></span>
                       <span class="delete"><i class="far fa-trash-alt"></i></span></div>`;
  feedsText.appendChild(newComment);
  commentText.value = null;
  likeComment(newComment);
  deleteComment(newComment);
}

// 이벤트 추가
commentBtn.addEventListener("click",plusComment)

commentText.addEventListener('keypress', function (e) {
  if (e.key === 'Enter') {
    plusComment()
    }
})

댓글 좋아요/취소 기능

빈 하트 아이콘 클릭시 붉은 하트 아이콘으로 변경되도록 했다.
아이콘의 className과 삼항연산자 개념을 활용해 두 가지의 아이콘을 클릭할 때 마다 변경할 수 있었다.

// 함수 선언 : 댓글 좋아요/취소 함수
function likeComment(newComment) {
  const likeBtn = newComment.querySelector(".heart");
  likeBtn.style.cursor = "Pointer";
  likeBtn.addEventListener("click",function() {
    event.target.className = event.target.className === "far fa-heart" ? "fas fa-heart" : "far fa-heart";
})}

댓글 삭제 기능

// 함수 선언 : 댓글 삭제 함수
function deleteComment(newComment) {
  const deleteBtn = newComment.querySelector(".delete");
  deleteBtn.addEventListener("click",() => newComment.remove());
  deleteBtn.style.cursor = "Pointer";
}

느낀 점

top-down 방식의 CSS를 bottom-up방식으로 바꾸며,
댓글 좋아요/취소 기능 구현중 이벤트버블링 등 개념을 처음 접하며 모르고 있는 개념이 너무나 많구나 또 한 번 느꼈다.
우선 이번에 배운 CSS개념은 앞으로도 놓치지말고 쭉 갖고가고,
javascript의 넓디넓은 개념도 쑥쑥 흡수해나가자.

profile
일상의 성실이 자존감을 만드는 성취주의자

3개의 댓글

comment-user-thumbnail
2021년 8월 16일

우와 짱 잘 만드셨네요...제가 나중에 API 개발해서 서버 열어드릴게요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ(희망사항)

1개의 답글
comment-user-thumbnail
2021년 8월 16일

댓글에도 Hello World! 적는 찐 개발자 동희님 🤭
깔끔한 코드가 정말 인상 깊었습니다!
수고하셨고! 리액트에서도 힘내봐요 함께! 💪

답글 달기