Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2주차 기본/심화 과제] 웹 투두메이트 #5

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

borimong
Copy link
Contributor

@borimong borimong commented Apr 17, 2023

✨ 구현 기능 명세

  • 기본 과제
    ‼️‼️‼️ 할일 목록 데이터는 상수파일에 저장해 사용합니다 ‼️‼️‼️ V

✅ 하트 안의 숫자V

  1. 미완료한 할일의 갯수를 계산하여 보여줍니다.V
  2. 할 일 완료 클릭시 갯수가 줄어듭니다.V

✅ 카테고리별 할일 추가V

  1. 카테고리별 할일 추가가 가능합니다.V
  2. 모달을 띄워 진행합니다V

✅ 달력 / MY 버튼 클릭시 페이지 이동V

  1. 달력 → href=”/” V
  2. MY → href=”/mycategory”V

🌼 PR Point

  • ~ 부분 이렇게 구현했어요, 피드백 부탁해요!
  1. 가능한 한 모두 독립된 함수로 구현하려고 했어요!
  2. 할 일의 개수는
    let checkedLength 를 이용해서 전역 변수로 관리했습니다!
  3. index.js
category.addEventListener("click", (event) => {
  if (event.target.classList.contains("todoAddButton")) {
    const modalContainer = document.querySelector(".modalContainer");
    modalContainer.style.display = "block";

    const modalAddButton = document.querySelector(".modalAddButton");
    modalAddButton.addEventListener("click", () => {
      const newTodoName = document.querySelector(
        ".modalContainer > input"
      ).value;

      data.map((datum) => {
        console.log(event.target);
        if (datum.title === event.target.getAttribute("title")) {
          const todo = datum.todos.map((todo) => {
            return todo;
          });

          const newTodo = `<h6>
            <img
            src="${
              datum.checked[datum.todos.indexOf(todo)]
                ? "./assets/favorite_FILL1_wght400_GRAD0_opsz48 (1).svg"
                : "./assets/favorite_FILL0_wght400_GRAD0_opsz48 (1).svg"
            }"
            alt="할-일을-완료했는지-체크하는-하트-아이콘"
            class="heartButton"
          />
          ${newTodoName}
            </h6>`;

          const categoryContent = document.querySelector(
            `.categoryContent[title=${event.target.getAttribute("title")}]`
          );

          categoryContent.insertAdjacentHTML("beforeend", newTodo);
        }
      });
      modalContainer.style.display = "none";
      event = null;
      const input = document.querySelector(".modalContainer input");
      input.value = null;
    });
  }
});

제가 가장 시간을 많이 쓴 부분이 바로 이 부분인데요,, 추가하기 버튼을 두 번이상 누르면, addEventListener 가 기존에 들었던 click 까지 모두 기억해서, 기존까지 클릭했던 모든 카테고리에 요소들이 추가되더라구요..! 어떻게 해결할까 고심하다가, 그럼 그동안 들었던 이벤트를 강제 초기화시켜주면 되지 않을까? 생각해서 event 에 null 을 넣어봤는데, 의도한 대로 동작해서 문제를 잘 해결했습니다..!!

🥺 소요 시간, 어려웠던 점

  • 6h
  • 저 event = null 부분 생각하기 전까지 온갖 시행착오를 겪었었습니다.. 처음에는 각각의 카테고리 대해서 이벤트 리스터를 맵으로 돌려서 붙여볼까 생각해서 시도도 해 보고.. 하다가 그럼 또 하트의 개수를 총망라해서 관리하기가 힘들어져서.. 최대한 카테고리 전체에 이벤트 리스너를 붙여서 이벤트 버블링으로 관리하게끔 했습니다..!!

🌈 구현 결과물

2023-04-21.8.23.06.mov

심화과제1
화면_기록_2023-06-14_오후_11_48_37_AdobeExpress

심화과제3
화면_기록_2023-06-14_오후_11_49_48_AdobeExpress

영상-심화과제1

2023-06-14.11.53.07.mov

영상-심화과제3

2023-06-14.11.55.42.mov

Copy link
Member

@simeunseo simeunseo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아뉫 어떻게 이렇게 스마트하게 짤 수 있는거야 ~~ 코드가 술술 잘읽히네!
하나 제안하고 싶은건,
함수를 선언하고 호출하고, 함수를 선언하고 호출하고 이런식으로 코드가 짜여있는 것 같은데 선언부랑 호출부의 영역을 나누어주면 좀더 어떤 로직으로 굴러가는지 이해하기가 좋을거같다는 의견 ! ㅎㅎ
고생 많았어~~

}
});
modalContainer.style.display = "none";
event = null;
Copy link
Member

@simeunseo simeunseo Apr 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가하기 버튼을 두 번이상 누르면, addEventListener 가 기존에 들었던 click 까지 모두 기억해서, 기존까지 클릭했던 모든 카테고리에 요소들이 추가되더라구요..! 어떻게 해결할까 고심하다가, 그럼 그동안 들었던 이벤트를 강제 초기화시켜주면 되지 않을까? 생각해서 event 에 null 을 넣어봤는데, 의도한 대로 동작해서 문제를 잘 해결했습니다..!!

와 진짜 나도 이 문제 때문에 머리 다 빠질뻔했거든???? 근데 event를 null로 초기화 할 생각을 한다고?!!!! ㄴㅇㄱ 천재야
나는 '모달을 클릭하는 부분'이랑 '할일추가를 처리하는 부분'을 따로 분리했더니 해결이 되더라고!! 모달을 오픈하는 event가 중첩되어서 발생하는 문제다보니까, 할일 추가 모달을 열고닫는거랑 할 일을 실제로 추가하는 거랑 로직적으로 전혀 관계가 없게 만든거지.. 아무튼 event에 null을 넣을 수도 있다는 생각의 전환! 배워갑니다 진짜 창의적이다 ㅎㅎ

const myCategoryButton = document.querySelector(".myCategoryButton");

calendarButton.addEventListener("click", () => {
window.location.href = '/';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 하면
스크린샷 2023-04-27 오후 3 56 02
요 창으로 가버리는 것 같은데 '/' 말고 './'로 하면 되지 않으려나?@

</div>
<section class="calendar">
<article>
<time>월</time>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time 태그!! 쏘 시맨틱!!!

<button type="button" class="calendarButton">
<img
src="./assets/home_FILL1_wght400_GRAD0_opsz48.svg"
alt="달력-페이지로-갈-수-있는-버튼의-아이콘"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상세한 alt 너뮤좋아요!!

const category = document.querySelector(".category");

function showCategory() {
const category_contents = data.map((datum) => {
Copy link
Member

@simeunseo simeunseo Apr 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옹 변수 이름을 datum으로 지은 이유는 뭐야?? 다툼?! 막이래..
data + num의 합성어인가? 뭘까

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다툼은 아닐거고

{
title: "솝트",
todos: ["1차 과제", "생각 과제"],
checked: [true, false, false],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옹?!! todos의 순서에 따라 checked여부를 나열한건가?! 만약 그렇다면 여기는 왜 세개지?!!

Comment on lines 80 to 98
data.map((datum) => {
console.log(event.target);
if (datum.title === event.target.getAttribute("title")) {
const todo = datum.todos.map((todo) => {
return todo;
});

const newTodo = `<h6>
<img
src="${
datum.checked[datum.todos.indexOf(todo)]
? "./assets/favorite_FILL1_wght400_GRAD0_opsz48 (1).svg"
: "./assets/favorite_FILL0_wght400_GRAD0_opsz48 (1).svg"
}"
alt="할-일을-완료했는지-체크하는-하트-아이콘"
class="heartButton"
/>
${newTodoName}
</h6>`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 있지 구현결과물 영상 보니깐, 미완료한 할일의 수를 체크하는건데 현수가 완료된 할일의 수를 체크하는 걸로 헷갈린거같다?!! 하트가 비워진 일들의 개수를 구해야되는데 하트가 채워진 일의 개수가 보여지고 있어 ㅎㅎ
그래서 만약 그걸 고치게된다면, 할일을 추가 했을 때 미완료 할일의 수가 +1되는 처리가 필요할거같아!

Comment on lines 143 to 157
& > button {
width: 4rem;
height: 4rem;
margin: 0.3rem;

border: none;
border-radius: 1rem;

cursor: pointer;

background-color: #70a1ff;

font-family: "KyoboHandwriting2021sjy";

box-shadow: 0.1rem 0.1rem 0.1rem #5352ed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔한 개행 너무좋은데?! 😍

Copy link

@kwonET kwonET left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔하면서 이번에도 함수로 모듈화를 잘 했다는 생각이 든다!

고생했어 현수 ㅎㅎ

const category = document.querySelector(".category");

function showCategory() {
const category_contents = data.map((datum) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다툼은 아닐거고

Comment on lines 27 to 33
return `
<article class="categoryContent" title="${datum.title}">
<span>${datum.title}<button class="todoAddButton" title="${datum.title}">+</button></span>
${todo}
</article>
`;
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map과 return + 쿼리를 사용하면
이렇게 조건문 안에서 깔끔하게 html을 조정할 수 있구나를 알고 갑니다
굳굳!!

Comment on lines 54 to 61
) {
event.target.src =
"./assets/favorite_FILL0_wght400_GRAD0_opsz48 (1).svg";
checkedLength--;
} else {
event.target.src =
"./assets/favorite_FILL1_wght400_GRAD0_opsz48 (1).svg";
checkedLength++;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svg 파일도 filter로 하면 css단에서 색상 변경이
가능하더라고! 혹시 다른 파일로 바꿔서 색상 변경한 거면 참고해봐 ㅎㅎ

Comment on lines 77 to 78
".modalContainer > input"
).value;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 이렇게 input의 value를 가져올 수 있구나!
배워갑니다 ㅎㅎ

@borimong borimong changed the title [2주차 기본 과제] 웹 투두메이트 [2주차 기본/심화 과제] 웹 투두메이트 Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants