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

[1주차] 이나현 미션 제출합니다. #7

Open
wants to merge 32 commits into
base: master
Choose a base branch
from

Conversation

CSE-pebble
Copy link

1주차 미션: Vanilla-Todo

🐻 배포 링크

https://agijagi-todo-blue.vercel.app/

👩‍💻 구현 기능

기본 기능

  • 할 일 추가, 완료, 삭제
  • Progress Bar로 할 일 완료 현황 확인
  • 오늘 날짜 세팅
  • Local Storage를 이용하여 기존 데이터 불러오기

추가 기능

  • 할 일 모두 완료/미완료에 따른 Progess Bar 텍스트 동적 업데이트
  • 오늘 날짜에 요일 추가
  • 할 일 중복 추가 예외 처리

🥳 후기

오랜만에 Vanilla JS로 기능을 구현하려니까 React가 정말 편리하다는 것을 다시 한 번 느끼게 되었습니다.. localStorage를 처음 알게 되었는데 너무 유용한 기능이네요! 가벼운 토이 프로젝트 할 때 유용할 것 같아요. 빨리 React도 쓰고 싶습니다 ㅎㅎ

💡 새롭게 배운 점

  • localStorage, sessionStorage의 개념과 활용

  • filter 메서드의 활용: 어떤 기능인지만 알고 있던 메서드를 직접 과제 기능 구현을 하는데 써보면서 filter 메서드의 유용성을 알게 되었습니다.

  • appendChild()의 중요한 특징: Todo->Done 이동할 때(Done->Todo도 마찬가지) done의 ul에 li를 appendChild() 메소드로 추가하고, todo의 ul에서는 해당 li를 remove 해주어야 한다고 생각했는데, done에 appendChild()만 해줘도 todo에서 자동으로 remove 되는 현상이 발생했습니다!😮 원하던 기능이라 이게 왜 되지..?? 했는데..!

    appendChild() 메소드는 한 노드를 특정 부모 노드의 자식 노드 리스트 중 마지막 자식으로 붙입니다. 만약 주어진 노드가 이미 문서에 존재하는 노드를 참조하고 있다면 appendChild() 메소드는 노드를 현재 위치에서 새로운 위치로 이동시킵니다. (문서에 존재하는 노드를 다른 곳으로 붙이기 전에 부모 노드로 부터 지워버릴 필요는 없습니다.)

    우왕.. 또 새롭게 알아갑니다!

  • 웹 접근성의 의미: 참고 자료에서 알게된 내용입니다.

    고령자, 장애인 같은 신체적, 환경적 조건에 제한이 있는 사용자를 포함해 모든 사용자들이 동등하게 접근할 수 있는 웹 콘텐츠를 제작하는 방법을 말합니다.

    이전까지는 웹 접근성이라는게 그냥 단순히 사용자가 웹 페이지에 잘 접근할 수 있는 정도를 의미하는 줄 알았는데 이런 의미를 지니고 있었다니.. 정말 중요한 개념이네요.

    그리고 img 태그의 alt 속성이 이미지 로드에서 오류가 났을 때 대체할 텍스트를 위한 용도라고 생각했는데, 이것이 img 콘텐츠를 텍스트화 하기 위해서도 사용될 수 있다는 것도 알게 되었습니다.

  • innerText vs. textContent

    textContent는 <script><style> 요소를 포함한 모든 요소의 텍스트 콘텐츠를 가져옵니다. 반면 innerText는 "사용자에게 보여지는" 요소의 텍스트 콘텐츠만 가져옵니다.

    이 블로그의 예제를 보면 아주 잘 이해할 수 있습니다.

🔥 어려웠던 부분 / 의문점

  • localStroage 기능 구현: 처음 다뤄보는 기능이라 시간이 꽤 걸렸습니다. 전역 배열을 생성하는게 싫어서 innerHTML을 이용하는 등 다른 방식으로 시도해봤으나.. 실패하고 결국 빙빙돌아 다시 배열을 생성하는 방식으로 구현했습니다.
  • 제 코드가 과연 효율적일지 의문이 듭니다. 특히 moveItem, deleteItem 함수에서 isDone을 확인하고 if문으로 그에 따른 처리를 해주는 부분이 마음에 들지 않습니다.😑

✨ 더 구현해보고 싶은 기능

  • 모바일 화면 반응형
  • CSS 단위: 반응형 CSS 단위에 대한 공부가 좀 더 필요할 것 같습니다.🥲 px 대신 rem을 적극적으로 활용해보고 싶어요!
  • form 태그 이용: form 태그가 웹사이트에서 회원가입이나 로그인, 검색창과 같은 사용자 정보 데이터를 입력 받아 서버로 전송할 때 사용한다는 것은 알고 있는데, 어떻게 사용해야 할지 확실히 모르겠어서 form 태그 없이 기능을 구현했습니다. 효율적인 데이터 전송에 도움이 되는 것 같아 이용해보고 싶습니다!

❓ Key Questions

1. DOM은 무엇인가요?

DOM(Document Object Model, 문서 객체 모델)은 HTML, XML 문서의 Programming interface 이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다

DOM은 Javascript가 HTML에 접근하여 제어할 수 있도록 하는 도구이다.
웹페이지 문서의 구조를 표현하는 HTML은 컴퓨터에게는 그냥 줄글일 뿐이고, 이를 구조화하기 위하여 HTML parser를 통해 DOM tree를 생성한다.

image

이 DOM tree는 HTML 태그를 객체로 바꿔줘서, Javascript가 이 객체의 다양한 프로퍼티와 메소드(DOM API)를 통해 웹 페이지를 제어할 수 있게 된다.

DOM API에는 querySelector, innerText, nodeList, classList, addEventListener 등이 있다.

2. HTML (tag) Element를 JavaScript로 생성하는 방법은 어떤 것이 있고, 어떤 방법이 가장 적합할까요?

  1. document.createElement("태그명")

    const newElement = document.createElement("div");

    태그 이름을 인수로 전달하여 새 HTML 요소를 만든다.

  2. innerHTML

    const container = document.getElementById("container");
    container.innerHTML = "<div></div>";

    부모 요소의 innerHTML 속성을 통해 HTML 문자열을 삽입하여 새 요소를 추가한다.

  3. insertAdjacentHTML(위치, 텍스트)

    const container = document.getElementById("container");
    container.insertAdjacentHTML("beforeend", "<div></div>");

    지정된 위치에 HTML 문자열을 삽입하여 새 요소를 추가하는 메서드이다. 위치는 target HTML Element의 앞(beforebegin), 뒤(afterend), 첫번째 자식(afterbegin), 마지막자식(beforeend)으로 지정할 수 있다.

위의 3가지 방법 중 document.createElement("태그명")가 가장 적합하다. innerHTML이나 insertAdjacentHTML()는 문자열이 그대로 HTML로 파싱되어 삽입하기 때문에, 웹 페이지에 악성 스크립트를 삽입하는 XSS(Cross-Site Scripting) 공격에 취약하다.

3. Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?

Semantic tag란?

<div>, <span>과 같이 의미는 없지만 구역을 나누기 위한 태그를 넘어서, 의미를 가지는 태그를 말한다.

Semantic tag의 종류

image

  • <header> : 사이트의 헤더 영역에 사용, 주로 사이트의 로고나 이름 등이 포함된다.

  • <nav> : 내비게이션을 의미하는 태그로, 주로 메뉴 영역에 사용된다.

  • <main> : 메인 컨텐츠 영역에 사용되며, <section>, <article>, <aside> 등이 포함된다.

  • <section> : 주로 <article>을 포함하는 태그로 섹션별로 나눠줄 때 사용한다.

  • <article> : 개별 콘텐츠, 반복되는 콘텐츠를 나타낼 때 사용한다.

    <section><article>의 차이
    <section>은 주요 콘텐츠의 구역을 나누는데 사용되고, <article>은 블로그 포스팅 글, 기사 글 같이 독립적인 콘텐츠를 나타낼 때 사용된다.

  • <aside> : 메인 컨텐츠 이외의 내용을 담을때 주로 사용한다. 보통 광고나 사이드바에 사용된다.

  • <footer> : 페이지의 하단에 주로 고객센터나 회사 정보를 담을때 사용한다.

Semantic tag 사용 이유

시맨틱 태그를 사용하는 이유는 다음과 같다.

  1. 웹 접근성 향상

    시각장애인이 스크린 리더 등을 사용했을 경우, 시맨틱 태그를 통해 사이트의 구조를 더욱 쉽게 이해할 수 있다. 예를 들어, <nav>의 경우, 콘텐츠에 탐색 링크가 포함되어 있음을 나타낼 수 있고, <article>의 경우에는 독립형 콘텐츠가 포함되어 있음을 나타낼 수 있다.

  2. 검색 엔진 최적화(SEO)

    Google과 같은 검색엔진은 태그를 기반으로 페이지의 주요 키워드를 파악한다. 예를 들어 글 제목에 h1 태그를 쓰거나 본문에 main 태그를 쓰면 그걸 바탕으로 키워드를 추출하고 검색에 노출시킨다. 따라서 시맨틱 태그는 관련 키워드와 문구에 대해 웹페이지를 최적화하는 데 도움이 되며, 이를 통해 검색결과 상에서 웹 사이트 노출 순위를 높이고 더 많은 트래픽을 유도할 수 있다.

  3. 코드 유지보수와 가독성

    시맨틱 태그의 이름 자체가 해당 요소의 역할을 설명하기 때문에 다른 개발자가 코드를 이해하고 수정하기 쉬워진다.

4. Flexbox Layout은 무엇이며, 어떻게 사용하나요?

Flexbox는 유연한 박스 모델을 사용하여 요소 간의 배치를 효율적으로 제어하는 레이아웃 방식이다. Flexbox를 사용하면 요소의 크기를 동적으로 조정하고, 정렬 및 배치를 쉽게 설정할 수 있다.

Flexbox는 Flex Container와 Flex Item으로 구성된다. Container은 Flex의 영향을 받는 전체 공간이고, Item들은 설정된 속성에 따라 특정 형태로 배치된다.

  • Flex Container에 적용하는 속성들: display:flex, flex-direction, flex-wrap, flex-flow(flex-direction+flex-wrap), justify-content, align-items, align-content

  • Flex Item에 적용하는 속성들: flex-basis, flex-grow, flex-shrink, flex(앞의 3개를 다 합친 것), align-self, order, z-index

5. JavaScript가 다른 언어들에 비해 주목할 만한 점에는 어떤 것들이 있나요?

  1. 인터프리터 언어

    자바스크립트는 인퍼프리터 언어이다. 인터프리터 언어는 프로그래밍 언어를 컴파일하여 기계 언어로 바꾸지 않고, 프로그래밍 언어로 되어 있는 코드를 한줄씩 읽으며 실행한다. 그렇기 때문에 컴파일이 필요한 다른 프로그래밍 언어에 비해 시간이 적게 소요된다.

  2. 동적 타입

    자바스크립트는 변수에 타입이 정해져 있지 않다. 컴파일 타임(소스 파일이 실행 파일로 만들어 지기까지의 시간)이 아니라 런타임(실행 파일이 실행되어 종료되기 까지의 시간) 시 변수의 타입이 결정된다. 따라서 유연성이 높고 컴파일 시 타입을 명시해주지 않아도 되기 때문에 개발 속도가 향상된다.

    참고 자료 1, 참고 자료 2

6. 코드에서 주석을 다는 바람직한 방법은 무엇일까요?

주석에 의존하기 보다는 깔끔하고 표현력이 좋은 코드를 작성하는 것이 좋다.
하지만 코드만으로도 의도를 표현하기 힘들다면, 기능/함수 단위로 명확하고 간결한 주석을 달아준다.

앞으로 할 일을 주석으로 써두는 경우도 있다.

- 전체 폰트 적용
- Header HTML&CSS 설정
- Todo input HTML&CSS 설정
- Todo/Done HTML&CSS 설정
- 시맨틱 태그에 기본적으로 적용된 스타일 제거
- 스타일 제거에 따른 CSS 코드 리팩토링
- 오늘 날짜를 세팅해주는 기능
- 할일 추가 기능 구현
- Todo/Done X버튼 누르면 삭제
- Todo/Done에 hover시 transition 적용
- 로컬 스토리지에서 done 리스트들을 가져올 때 리스트 모두에 done class를 넣어줌
- input에 공백이 있을 경우 제거해줌
- 오늘 할일을 모두 완료했으면 텍스트가 바뀌는 기능 구현
- 날짜에 요일도 표시
- 주석 추가/삭제
- Todo/Done이 아무것도 없을 경우 텍스트 세팅
Copy link

@westofsky westofsky left a comment

Choose a reason for hiding this comment

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

안녕하세요~~ 프론트 파트장 배성준입니다🎨

여러가지 css효과랑 귀여운 디자인 보면서 재미있게 리뷰했습니다~~
새롭게 배우신 점이 많은 것 같아 같이 성장하는 기분이 드네요!! 저도 많이 배운 것 같습니다~~
몇가지 참고 할 만한 것들 리뷰 달아서 참고만 해주시면 될 것 같아요!
구현해보고 싶은 기능을 다음 과제에 적용해보세요!!! 고생하셨습니다~

Comment on lines +14 to +15
const month = ("0" + (today.getMonth() + 1)).slice(-2);
const day = ("0" + today.getDate()).slice(-2);

Choose a reason for hiding this comment

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

String.prototype.padStart 를 이용해서 구현 할 수도 있을 것 같아요!

Suggested change
const month = ("0" + (today.getMonth() + 1)).slice(-2);
const day = ("0" + today.getDate()).slice(-2);
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');

Comment on lines +21 to +25
// Local Storage에 저장
const setLocalStorage = () => {
localStorage.setItem("todo", JSON.stringify(todoArr));
localStorage.setItem("done", JSON.stringify(doneArr));
};

Choose a reason for hiding this comment

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

로컬스토리지 구현까지 정말 짱짱입니다!

script.js Outdated
Comment on lines 29 to 30
const todo = JSON.parse(localStorage.getItem("todo"));
const done = JSON.parse(localStorage.getItem("done"));

Choose a reason for hiding this comment

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

localStorage가 비어있으면 null을 반환해서 이후에 forEach를 돌면 아래와 같이 오류가 나는 것 같아서 예외처리해주면 좋을 것 같습니다!
image

Suggested change
const todo = JSON.parse(localStorage.getItem("todo"));
const done = JSON.parse(localStorage.getItem("done"));
const todo = JSON.parse(localStorage.getItem("todo")) || [];
const done = JSON.parse(localStorage.getItem("done")) || [];

script.js Outdated
Comment on lines 70 to 79
const progressBarCount = document.querySelector(".progress-box__count");
progressBarCount.textContent = `${doneCount} / ${totalCount}`;

const progressBarDone = document.querySelector(".progress-box__bar-done");
let doneRatio = 0;
if (totalCount !== 0) doneRatio = (doneCount / totalCount) * 100;
progressBarDone.style.width = `${doneRatio}%`;

// 텍스트 세팅
const progressText = document.querySelector(".progress-box__text");

Choose a reason for hiding this comment

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

document.querySelector가 함수 내에 있어서 updateItemCount를 호출할때마다 DOM에 접근해야해서 한번만 선택하도록 해주면 좋을 것 같습니다!

Comment on lines +141 to +150
// 예외처리: 할일 중복 X
if ([...todoArr, ...doneArr].includes(todoInputText)) {
// 중복 할일 X
alert("이미 존재하는 할 일 입니다!");
todoInput.value = "";
return;
}

// 예외처리: 할일 공백 X
if (!todoInputText) return;

Choose a reason for hiding this comment

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

예외처리까지 구현해주셨네요ㅎㅎ 고생하셨습니다 !!

script.js Outdated

// 아이템 삭제 함수
const deleteItem = (e) => {
const todoListNode = e.target.parentElement.parentElement;

Choose a reason for hiding this comment

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

투두 열심히 작성하다가 가끔 삭제를 눌렀을 때 전체가 삭제되고 아무것도 안보여서 확인해보니 구조가

<ul>
  <li>
    <span></span>
    <button>
      <i></i>
    </button>
  </li>
</ul>

의 구조에서 <i> 를 누르면 e.target.parentElement.parentElement;<li>가 돼서 원하는대로 동작을 하지만 <i>영역이 아닌 그 외에 <button>영역을 선택하면 e.target.parentElement.parentElement;<ul>이 되어서 사라지는 것 같습니다..!
어떻게 하면 비슷하게 동작할까 검색해보니 event.target.closet()을 이용해서 가장 가까운 조상(<li>)을 찾아서 삭제하면 될 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

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

대박 너무 좋은 메서드 알아갑니다!!! 이렇게 수정하니까 가독성도 너무 좋아졌어요 감사합니다!

style.css Outdated
Comment on lines 128 to 131
.todo-box li span {
cursor: pointer;
transition: color 0.1s ease-out;
}

Choose a reason for hiding this comment

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

당연히 그런 사람은 없겠지만 .. 사진과 같이 영어를 입력하면 넘어갈 수 있어서 간단한 word-break : break-all; 하나 추가해주시면 좋을 것 같아요!

Suggested change
.todo-box li span {
cursor: pointer;
transition: color 0.1s ease-out;
}
.todo-box li span {
cursor: pointer;
transition: color 0.1s ease-out;
word-break : break-all;
}

Copy link
Author

Choose a reason for hiding this comment

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

언어에 따라 줄바꿈 규칙이 다르다는 것을 처음 알았습니다...............
감사합니다!
나중에 다시 봐야징


.todo-box li span {
cursor: pointer;
transition: color 0.1s ease-out;

Choose a reason for hiding this comment

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

transition 포인트 너무 좋습니다!!

script.js Outdated
Comment on lines 112 to 116
// Progess bar 업데이트
updateItemCount();
// Local Storage 업데이트
setLocalStorage();
};

Choose a reason for hiding this comment

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

중복되는 업데이트하는 코드들은 updateItmes() 함수를 만들어서 따로 관리해도 좋을 것 같아요!

style.css Outdated
Comment on lines 69 to 91
/*Progress Bar*/
.progress-box {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
column-gap: 10px;
padding: 15px 10px 6px 10px;
}

.progess-box__bar-whole {
background-color: #c0c0c0;
border-radius: 10px;
height: 15px;
position: relative;
}

.progress-box__bar-done {
background-color: #7f7f7f;
border-radius: 10px;
height: inherit;
position: absolute;
transition: width 0.4s ease-in-out;
}

Choose a reason for hiding this comment

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

프로그래스바로 한눈에 볼 수 있어서 좋은 것 같습니다!!

Copy link

@Programming-Seungwan Programming-Seungwan left a comment

Choose a reason for hiding this comment

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

reset.css를 적용하여 원하는 디폴트 스타일링을 적용하신 점, flex box에 그치지 않고 grid 시스템을 적극적으로 사용하신 점, 이미 존재하는 할 일을 가려내는 로직 예외 처리를 해주신 부분들을 보면서 많이 배울 수 있었습니다.

이번 주 과제 고생하셨습니다 :)

</div>
</section>
</main>
</div>
</body>
<script src="script.js"></script>

Choose a reason for hiding this comment

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

html 문서를 파싱하는 방법으로, body 태그가 끝나기 직전이나 끝난 직후, 혹은 head 태그 내부에서 script 태그에 defer 속성을 부여하여 dom 요소가 생성되기 전에 조작 오류가 나는 일을 방지하는 로직이 좋습니다 👍

</body>
<script src="script.js"></script>
<script
src="https://kit.fontawesome.com/4e5b2f86bb.js"

Choose a reason for hiding this comment

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

저는 css 파일에서 @font-face 문법을 활용하여 font를 사용했는데, cdn에 있는 리소스를 활용하시는 로직도 좋은 것 같습니다.

@@ -1 +1,143 @@
/* 본인의 디자인 감각을 최대한 발휘해주세요! */
@import "reset.css";

Choose a reason for hiding this comment

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

정의해주신 reset.css파일에서 기존의 브라우저 디폴트 스타일링을 방지하고 새롭게 정의하신 것을 사용하는 컨벤션을 잘 준수하시는 것 같습니다 :)

추가적으로 제가 나현님 코드에서 실수로 발견을 못했을 수도 있는데, box-sizing : border-box 속성을 통해 기존의 padding과 border 속성을 width, height에 포함시켜 margin만 추가적으로 고려할 수 있도록 하는 방식도 괜찮지 않을까 싶습니다!

<body>
<div class="container"></div>
<div class="container">

Choose a reason for hiding this comment

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

웹 페이지의 컴포넌트들을 header와 container로 나누신 것이 상당히 깔끔해 보입니다! 적용해주신 UI도 귀엽고 편안한 이미지 위주로 구성하신 것 같구요!
다만 이를 모바일 디바이스 환경에서 봤을 때 글씨 크기가 다소 크다는 느낌이 있어서 media query를 이용해 768px 이하에서 약간 작은 폰트로 적용해주시면 어떨까 싶어요.

  • section, main 같은 semantic 태그들도 잘 활용하신 것 같습니다 :)

</header>
<main>
<section class="input-box">
<i class="fa-solid fa-paw"></i>

Choose a reason for hiding this comment

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

저 같은 경우에는 fontawesome에서 아예 이미지를 따와서 적용해 주었는데, 아예 i 태그의 class를 활용해서 svg 이미지를 구현하신 것도 괜찮은 것 같아요

}

/*Progress Bar*/
.progress-box {

Choose a reason for hiding this comment

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

저 같은 경우에는 아예 flex 박스 컨테이너로 레이아웃을 구성했는데, 아예 grid 시스템을 사용하신 것도 좋아보여요. 저는 flex box에서 flex-growflex-shrink 속성을 통해 해당 아이템이 차지할 너비를 결정했는데 grid-template-columns 속성으로 한번에 처리하는 것이 더 낫겠네요! 잘 배워갑니다 :)

script.js Outdated
Comment on lines 22 to 30
const setLocalStorage = () => {
localStorage.setItem("todo", JSON.stringify(todoArr));
localStorage.setItem("done", JSON.stringify(doneArr));
};

// Local Storage 불러오기
const loadLocalStorage = () => {
const todo = JSON.parse(localStorage.getItem("todo"));
const done = JSON.parse(localStorage.getItem("done"));

Choose a reason for hiding this comment

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

로컬 스토리지에 반영하는 로직과 UI에 동기화해주는 로직을 각각의 함수로 빼주신 부분은 재활용에 있어 좋다고 생각합니다

const todoInputText = todoInput.value.trim();

// 예외처리: 할일 중복 X
if ([...todoArr, ...doneArr].includes(todoInputText)) {

Choose a reason for hiding this comment

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

나현님께서 사용자가 입력한 todo가 이미 존재하는 것이라면 예외 처리와 early return 을 통한 로직 종료도 굉장히 좋아보입니다!

다만 사용자가 실제 애플리케이션을 사용할 때 설거지하기, 스트레칭 하기와 같은 같은 할 일을 추가하고 삭제하는 기능이 필요할 때도 있을 것 같아요. 사용하신 todoArrdoneArr 같은 경우에는 배열이기에 indexOf() 와 같은 메서드를 사용하는 것도 고려해봄직 하지만, 이는 배열의 가장 앞에 존재하는 요소의 인덱스를 반환하거나 없다면 -1을 반환하기 때문에 다른 방식으로 구현해보는 것도 좋을 것 같아요 :)

};

// 첫 화면 렌더링용 함수
const init = () => {

Choose a reason for hiding this comment

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

처음 웹 페이지가 dom에 마운트 될 시에 트리거할 로직을 함수로 작성한 것이 좋습니다.

Copy link

@noeyeyh noeyeyh left a comment

Choose a reason for hiding this comment

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

기능별로 가독성 있게 코드 작성하신 것 같아요!
저는 자주 사용하던 속성에만 익숙해져서 grid를 사용하지 않았는데 나현님 코드에서 grid도 함께 사용하신 것 보고 배워갑니다. 그리고 예외처리 같이 놓칠 수 있는 부분도 꼼꼼하게 작성하신 것 같아요.
주석도 세심하게 잘 작성하신 것 같아요. 덕분에 이해하는 데 도움이 되었어요!

<ul></ul>
</div>
</section>
</main>
Copy link

Choose a reason for hiding this comment

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

semantic tag를 적극적으로 사용하셔서 구조를 더 명확하게 이해할 수 있는 것 같아요.
<header> 태그 사용하신 거 보고 배워가요!


const progressBarDone = document.querySelector(".progress-box__bar-done");
let doneRatio = 0;
if (totalCount !== 0) doneRatio = (doneCount / totalCount) * 100;
Copy link

Choose a reason for hiding this comment

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

totalCount가 0인 경우 분모가 0이 되는 상황이 발생하는데 if 조건문으로 세심하게 잘 처리하신 것 같아요!

table {
border-collapse: collapse;
border-spacing: 0;
}
Copy link

Choose a reason for hiding this comment

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

저는 reset.css를 작성하지 않았는데 나현님 코드 보고 배워가요.
reset.css로 스타일을 초기화하고 작성하셔서 브라우저 호환성과 스타일 제어가 더 정확한 것 같아요!

script.js Outdated
const day = ("0" + today.getDate()).slice(-2);
const dayOfWeek = week[today.getDay()];

https: return `${year}.${month}.${day} ${dayOfWeek}요일`;
Copy link

Choose a reason for hiding this comment

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

https:는 혹시 잘못 작성하신 걸까요..?

Copy link
Author

Choose a reason for hiding this comment

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

으악 이게 뭘까요!! 수정했습니다 감사합니다!

const addTodo = () => {
// input에 입력한 값 가져오기
const todoInput = document.querySelector(".input-box input");
const todoInputText = todoInput.value.trim();
Copy link

Choose a reason for hiding this comment

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

중복된 할 일과 공백을 예외처리하신 것도 꼼꼼하게 잘하신 것 같아요.
이미 입력한 할 일을 다시 입력하면 alert창을 띄우는 것도 좋은 것 같아요!

index.html Outdated
</section>
<section class="progress-box">
<span class="progress-box__text"></span>
<span class="progess-box__bar-whole">
Copy link

Choose a reason for hiding this comment

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

progress가 progess로 오타난 것 같아요..! 아래 css에도 같아서 스타일은 적용된 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

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

아앗 class명 치기 귀찮아서 복붙한 보람(?)이 있네요..ㅎㅎ
꼼꼼하게 확인해주셔서 넘 감사합니다 수정했습니다~!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants