본문 바로가기
JS

[HTML/CSS/JS] to do list 만들어보기 회고

by 케찹이 2024. 2. 27.

https://main--transcendent-bunny-41a741.netlify.app/

배경이 다했다 ㅋㅋㅋㅋ

 

노마드 코더의 바닐라JS 크롬 앱 만들기 수업을 듣고 복습 그리고 지금까지 배웠던 HTML, CSS, Javascript를 연습할 겸 수업에서 다루었던 프로젝트를 다시 한번 직접 제작해보았다. 

 

사실 강의에서 기능들의 구현을 이미 상세하게 설명해주었기 때문에 대부분의 javascript에서 마주친 문제가 그렇게 크지는 않았다. 

다만 강의에서 설명하지 않았던 기능 그리고 강의에서 설명해주었지만 다시 직접 구현할때 떠올리기 어려웠던 인사이트는 다시 한번 적어 남겨보도록 하겠다.

어려웠덤 점들 - Javascript

1. 정해진 날짜와 현재 시간과의 날짜 계산

해당 앱을 만들면서 오른쪽 상단에 내가 언제부터 프론트 기술들을 공부하기 시작했는지에 대한 날짜를 작성하고 싶었다.

내가 프론트엔드를 공부하기로 다짐한건 2월 17일부터 였기 때문에 해당 날짜와 현재 날짜 사이의 차이를 계산하는 기능이 필요했다.

 

날짜를 계산할때 사용해야 하는 객체는 Date() 객체이다. 아래 작성한 코드를 보면서 한번 리뷰해보자.

function calculateDay() {
  const startDate = new Date("2024/02/17");
  const now = new Date();

  const diffTime = Math.abs(now.getTime() - startDate.getTime());
  const dayDif = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  dDay.innerText = `FrontEnd 공부한지 ${dayDif}일차`;
}

몇줄 안되지만 그래도 나름 머리를 굴리면서 작성한 코드이다.

일단은 생성자에 인자를 "2024/02/17"이런 문자열을 통해서 단순하게 일자를 초기화할 수 있다.

그리고 Date.getTime()은 역시나 1970년 1월 1일 기준과 떨어진 밀리 초를 나타내주는데, 덕분에 해당 값으로 지금 시각과 정해진 시각의 밀리초를 구할 수 있고 단위를 계산하기 위해서 (1000 * 60 * 60 * 24)를 나누어 준다. (각 초, 분, 시간, 일을 계산)

 

마무리로 몇일차를 계산하고 있다보니 4.1, 4.2일 모두 5일차로 생각하기 때문에 무조건 오름차수 처리하는 Math.ceil()으로 감싸주었다.

 

 2. to do list, localstorage 값 추가 제거

해당 강의를 들은 분들은 알겠지만 강의중 제일 어려운 부분이 바로 to do list 세션이다. 어려운 이유는 여러가지가 있겠지만 직접 구현하면서 어려웠던 인사이트는 javascript에서 생성한 element와 이미 html에서 생성된 element와의 연결점이였다.

 

헷갈렸던 부분은 이 부분이다.

function removeTodo(event) {
  const li = event.target.parentNode;
  li.remove();
  toDos = toDos.filter((todoObject) => todoObject.id !== parseInt(li.id));
  saveToDos();
}

function paintToDo(todoObject) {
  const li = document.createElement("li");
  li.id = todoObject.id;
  const todo = document.createElement("span");
  todo.innerText = todoObject.todo;
  li.appendChild(todo);
  const doneButton = document.createElement("button");
  doneButton.innerText = "✅";
  doneButton.addEventListener("click", doneTodo);
  li.appendChild(doneButton);
  const removeButton = document.createElement("button");
  removeButton.innerText = "❌";
  removeButton.addEventListener("click", removeTodo);
  li.appendChild(removeButton);
  todoList.appendChild(li);
}

to do list중 <ul>은 이미 html에 작성되어 있는 부분이고 <ul>안에 들어갈 <li>와 또 그안에 들어갈 <span>과 <button>을 만들어주는 과정이다. 여기까지는 어려운 부분이 없다.

 

처음으로 헷갈리는 부분은 해당 to do를 삭제하는 removeTodo()였다. 해당 버튼이 눌리면 버튼이 위치한 li를 삭제해야 하는데 localStorage에 to do내용과 저장하는 시간(id)을 저장하기 때문에 이를 사용해서 어떻게 li를 지울까가 어려웠던 부분이다.

이때 썼던게 event.target.parentNode였다. 해당 부분은 console.dir(event.target)을 통해서 parentNode값의 li가 버튼의 부모인 li를 가리키고 있다는 것을 표시해주었고 덕분에 해당 li를 삭제할 수 있었다.

또한 이 id값 때문에 전체 to do내용을 관리하는 toDos집합도 object 형태로 to do 내용을 저장해두었다. 여기부터는 설명이 좀 이상해졌는데 어쨌든 위에서의 생성 element들과의 연결점을 찾는데에 어려움 때문에 여러가지 어려움이 있었다.

 

어려웠덤 점들 - CSS

CSS를 예전부터 얕잡아 봤었는데 요 몇일새에 직접 한땀한땀 CSS를 작성하다보니, CSS의 문턱이 이렇게 높은지 실감하고 있다.

뭐 여러 문제점이 있었지만 가장 머리 아팠던 문제는 position이였다.

 

~발단~

문제의 발단은 to do를 작성하는 input 스타일에서 시작했다. 

아무래도 to do list를 작성하는게 해당 서비스의 메인 기능이였기 때문에 이와 관련된 input의 스타일을 조금 화려하게 만들고 싶다는 욕심이 있었다. 그래서 구글링을 통해서 나름 멋진 디자인의 input을 가져왔다.

See the Pen Untitled by 이찬 (@vexkruqa-the-typescripter) on CodePen.

 

 

해당 코드를 보면서 "오~ input:focus가 됐을 때 label에게 효과를 주네? focus인 동시에 input에 required 조건이 있으니까 input:valid를 통해서 효과를 유지하네?" 하면서 이런저런 문법을 이해하고 있었다.

 

~전개~

해당 코드를 내 코드에 적용시키려다 보니까 막혔던 부분이 앞서 말했던 position이였다.

내 코드를 살펴보면 .main-content라는 div에 포함된 부분들이 text-align: center를 통해서 중앙 정렬이 되어있는 상태이고 .main-content의 부모 element인 body는 그냥 position: static인 상황이었다.

 

그러다보니까 위에 있는 효과를 적용하면서 기존에 있는 main-content안에서 중앙 정렬을 유지시키기가 매우 복잡하다는 것을 알게 되었다. 하필 해당 효과를 거의 맨마지막에 적용하려다보니 기존 html코드를 다 뒤엎어야 겠다 라는 생각이 들었다.

 

결론은 해당 효과를 적용하지 않았지만 여러 css에서의 position을 배웠고 html을 작성하기전에 어떤 position을 사용해야 할까? 라는 고민을 하게 된것 같다.

 

아래 블로그를 통해서 position: relative, absolute, fixed에 배웠는데 정말 짧게 정리하면 다음과 같은 특징이 있다.

position: relative , 현재 위치한 곳에서 얼만큼 떨어질지를 정할 수가 있다. 그래서 검사 도구 창에서 element클릭하면 실제 위치보고 떨어진 곳에 파랑색 위치가 표시되는 것을 알 수 있다.

position: absolute, 해당 position은 부모의 위치 기준으로 해당 element의 위치를 정한다. 부모중에는 relative, absolute, fixed중 하나라도 있어야 하며 해당 부모 기준으로 움직이게 된다.

position: fixed, 해당 position은 viewPort기준으로 자리를 정한다. 간단히 말하자면 화면을 스크롤해도 그 자리에 고정되게 하는 기능이다.

참고: https://velog.io/@remon/position-%EC%9D%B4%EB%9E%80

 

~결말~

해당 기능은 결국 끝내 적용하지는 못했다. 다만 이번 문제를 통해서 깨닳은 것은 html, css를 구현하기 전에 충분한 시간을 두어 display뿐만 아니라 position또한 어떻게 구성할지 머리로 한번 생각을 하고 구현해야 한다는 것이다.

 

아직 flex, grid에 미숙하고 position에 관련된 부분도 직접 사용할때는 많은 문제를 마주치고 있다. 다음 토이플젝에는 display, position을 어떻게 써야할지 많은 고민을 하고 활용법에 한번 익숙해져야겠다.

 

+) 반응형 웹도 만들어야 하는데 휴... 자꾸 시간 없다고 미루는데 본 프로젝트 들어가면 어려워할게 뻔히 보인다 ㅜ 다음엔 꼭 반응형 웹도 적용하자!

'JS' 카테고리의 다른 글

VanillaJS로 웹서비스 만들기 - 중간 검토1  (0) 2024.03.03
flex 개념, 특징 정리  (0) 2024.02.27
ES6 Promise 연습문제  (0) 2024.02.25
constructor, prototype 연습문제  (0) 2024.02.24
Spread, rest 파라미터 연습문제  (0) 2024.02.24

댓글