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주차] 오대균 미션 제출합니다. #1

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

Conversation

oooppq
Copy link

@oooppq oooppq commented Sep 11, 2023

1주차 미션: Vanilla-Todo

배포

오대균의 Todo List

Key Features

  • todo 추가, 제거, 완료
  • 중요도 및 기한 설정(width: 500px 이상일 때)
  • 중요도 및 기한(시작일)을 기반으로 정렬된 list
  • 중요도에 따라 다른 글자색(중요도가 높을 수록 더 진하게)
  • 완료된 todo는 list의 가장 아래에 배치, 글자색 매우 연하게
  • 눈누 웹폰트 적용
  • localStorage를 사용하여 list 저장

Key Questions

  • DOM은 무엇인가요?

    Document Object Model의 줄임말로, html로 작성된 코드를 object 기반으로 표현한 것입니다. object로 표현한다면 해당 웹을 프로그래밍 언어로 직접 조작할 수 있습니다.

    DOM은 트리 구조로 구성됩니다. html로 작성된 여러 tag들이 object로 parsing되고, 작성된 구조에 맞게 tree를 형성하게 됩니다.

    대표적으로 JavaScript를 통해 DOM을 조작할 수 있습니다. 형성된 html element를 참조하여 값을 읽거나 변경할 수 있고, 새로운 element를 만들어 삽입할 수도 있습니다.

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

    JavaScript에서 기본적으로 제공하는 내장 method인 document.createElement()를 사용하면 쉽게 생성할 수 있습니다. 해당 method에 원하는 tag를 string 형식으로 전달하면 새로운 element 객체를 return해줍니다.

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

    header, nav, main, footer, article, section 등이 있습니다. 일반적으로, Semantic tag 그 자체로는 아무런 역할을 하지 않는 경우가 많고, 종종 내장된 속성이 있는 경우가 있습니다.

    Semantic tag는 이름 그대로, tag 자체에 의미가 있기 때문에 유용하게 사용될 수 있습니다. 예를 들어, header tag를 사용하여 뭔가를 작성한다면, 해당 내용이 웹의 header 부분에 들어갈 것이라고 짐작할 수 있습니다. 즉, tag 내부의 내용과 상관없이 tag 자체로 역할을 정의하고 인식할 수 있습니다.

    또한 SEO에 도움이 됩니다. tag를 기반으로 search engine이 웹을 탐색할 수 있고, 노출시키고 싶은 정보를 적절한 tag를 사용하여 search engine에게 명시적으로 노출시킬 수도 잇습니다.

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

    Flexbox 내부의 아이템 간의 공간 배분과 다양한 방식의 정렬 기능을 제공하는 1차원 레이아웃 모델입니다.

    기본적으로 css에서 display: flex 속성을 지정하면 해당 box는 flexbox가 됩니다.

    개인적으로 주로 사용하는 기능은 flex-direction(가로, 세로 방향 지정), justify-content, align-items(정렬), flex-grow(크기 자동) 등이 있습니다.

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

    web 생태계 전반적에 걸쳐 대부분의 도메인에서 사용할 수 있는 언어라는 것이 가장 큰 장점인 것 같습니다. 원한다면 어렵지 않게 풀스택 웹 프로젝트를 진행할 수 있습니다.

    범용적으로 사용되기 때문에 관련 지식을 인터넷 상에서 쉽게 얻을 수 있고, 수 많은 교육 자료와 레거시 코드들을 접할 수 있습니다.

    타입 지정이 필요 없다는 점은 장점이자 단점일 수 있습니다. 처음 배우는 입장에서는 타입이라는 생소한 개념을 신경쓰지 않아도 되기 때문에 편리할 수 있고, 계속 사용하다보면 어떤 타입의 data인지 확실하지 않아 에러가 발생하여 문제가 될 수 있습니다.

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

    가장 좋은 것은 주석이 필요 없을 정도로 가독성 좋은 코드를 작성하는 것이라고 생각합니다. 일단, 좋은 코드를 작성하려고 노력하고, 그렇게 해도 설명이 부족한 감이 있다면 최대한 간소화하여 주석을 작성하는 것이 좋은 것 같습니다.

    너무 장황하거나 빈번하게 작성된 주석은 오히려 코드의 가독성을 망치게 된다고 생각합니다. 만약, 필수적인 설명이 너무 길다면 따로 문서화하여 기록하는 것이 더 좋을 것 같습니다.

후기

React나 Next 등 javaScript를 기반으로 한 라이브러리 혹은 프레임워크 사용에 익숙해진 상태에서, 처음으로 돌아가 javaScript 문법만으로 원하는 결과물을 내려고 하니 굉장히 낯설었습니다.

특히, react를 사용할 때에는 react hook인 useState로 상태를 정의하여 손쉽게 logic과 view를 연결해 변경사항을 반영할 수 있었는데, vanilla js의 경우에는 logic과 view의 관계를 직접 정의하여 적절한 방식으로 화면에 display 시키는 것이 되게 번거로웠습니다.

뭐든지 기본이 가장 중요하다고 생각했는데, 이렇게 기본으로 돌아가 코딩할 수 있는 시간을 가질 수 있어서 매우 유익했습니다.

추가하면 좋을 점

  • 작성된 todo 수정(내용, 중요도, 기한)
  • transition을 이용한 애니메이션

앱 구동에 필요한 기본적인 html 코드를 작성했다.
todo list를 localStorage에서 가져오고 view에 display하는 기능을 구현했다.
done, delete 버튼에 onclick handler를 정의하여 클릭 이벤트에 반응할 수 있도록 했다.
add 버튼을 누르면 리스트에 추가되고, 메모리에서 관리되는 todo List가 priority와 date에 따라 정렬될 수 있도록
로직을 구성했다.
오늘 날짜보다 시작일이 빠르지 않고, 시작일보다 종료일이 빠르지 않도록 제한하는 기능을 추가했다.
script.js Outdated
@@ -0,0 +1,30 @@
// localStorage에서 todo elements 가져오기, 시간을 Date형식으로 변환하기 위해 map 함수를 사용

Choose a reason for hiding this comment

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

핵심적인 부문에 주석이 적용되어 이해가 편했습니다 ㅎㅎ

@@ -41,63 +52,81 @@ const addNewTodoLi = (todo) => {
deleteBtn.innerHTML = 'delete';
deleteBtn.className = 'deleteBtn';

doneBtn.addEventListener('click', handleClickDoneBtn);
deleteBtn.addEventListener('click', handleClickDeleteBtn);

newLi.appendChild(contentDiv);
newLi.appendChild(fromDateDiv);
newLi.appendChild(toDateDiv);
newLi.appendChild(doneBtn);
newLi.appendChild(deleteBtn);

Choose a reason for hiding this comment

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

저도 여러 개 노드들 추가할 때 appendChild를 반복해서 썼었는데, 다른 방법이 없을까 하고 찾아보니까 append() 를 사용하면 문자열을 포함해서 여러 개 요소들을 추가할 수 있는 것 같아서 참고하시면 좋을 것 같습니다 😀
https://choijying21.tistory.com/132

Copy link
Author

Choose a reason for hiding this comment

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

오 새롭게 알게되었네요~~ 다음에 element 추가할 때에는 append를 사용해보겠습니다~~

if (TODOS[i].fromDate >= todo.fromDate) break;
}
}
TODOS.splice(i, 0, todo);

Choose a reason for hiding this comment

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

splice 메서드의 두번째 매개변수를 0으로 지정해서 todo 값을 추가한 거 좋은 것 같습니다 ㅎㅎ 기존 배열에서 내가 원하는 값을 특정위치에 삽입할 때 유용하게 쓸 수 있을 것 같아요!

Comment on lines +169 to +170
newTodo.fromDate = fromDate.value ? new Date(fromDate.value) : new Date();
newTodo.toDate = toDate.value ? new Date(toDate.value) : new Date();

Choose a reason for hiding this comment

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

삼항 연산자를 통해 날짜를 등록하지 않았을 떄의 예외처리 까지 하신 것이 인상깊네요!

Copy link

@dhshin98 dhshin98 left a comment

Choose a reason for hiding this comment

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

안녕하세요 대균님! 코드가 너무 깔끔하고 주석도 디테일하게 달아주셔서 코드 이해가 잘됐습니다. 우선순위랑 날짜까지 선택할 수 있는 아이디어까지 참신하고 좋았던 것 같습니다~! 보면서 주석이랑 네이밍의 중요성에 대해 느꼈네요 ㅎㅎ 그리고 화면크기가 작아질때 고려해서 반응형으로 짜신것까지 인상깊었습니다!!

const toDate = document.querySelector('.to');

// input들의 value값을 newTodo에 저장
if (!content.value) return;

Choose a reason for hiding this comment

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

이 부분은 저도 리뷰를 받아서 알게 된 부분인데, input 입력시 스페이스바를 눌렀을때도 리스트에 추가되는데, trim()을 통해 공백을 제거하시면 빈 스페이스바 todo 를 방지할수 있다고 합니다!

Copy link
Author

Choose a reason for hiding this comment

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

아 그렇네요!! 고려하지 못한 디테일이었는데 덕분에 알게되었습니다 감사합니다~~

if (TODOS[i].fromDate >= todo.fromDate) break; // 시작일이 빠른 todo가 더 낲에 위치
}
}
TODOS.splice(i, 0, todo);

Choose a reason for hiding this comment

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

우선순위랑, 시작일에 따라 배치해서 보여주는 거 아이디어 좋은것 같아요!👏 그리고 따로 정렬조건 거치지 않게 push 할때 조건을 주니까 코드가 훨씬 효율적이네요!!

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 +168 to +181
.high {
color: black;
font-family: 'SUITE-SemiBold';
}

.mid {
color: rgb(120, 120, 120);
font-family: 'SUITE-Medium';
}

.low {
color: rgb(200, 200, 200);
font-weight: 400;
}

Choose a reason for hiding this comment

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

우선순위에 맞게 폰트까지 설정해주는 디테일까지...! 이렇게 하니까 디자인적으로 바로 시각화 되니까 좋은거 같아요

// 에러가 발생하지 않도록 삼항연산자로 분기
newTodo.fromDate = fromDate.value ? new Date(fromDate.value) : new Date();
newTodo.toDate = toDate.value ? new Date(toDate.value) : new Date();
newTodo.isDone = false;

Choose a reason for hiding this comment

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

isDone으로 todo랑 done 구분하는 방법도 직관적이고 좋은 것 같네요~!

Comment on lines +188 to +196
@media (max-width: 500px) {
.radioOuter,
.dateOuter,
.fromDate,
.toDate,
.betweenDate {
display: none;
}
}

Choose a reason for hiding this comment

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

와우 화면 크기가 500픽셀 이하인 경우 우선순위랑 날짜 요소 숨기면서 반응형으로 짜신거...너무 멋진거 같아요!!!! 👍 작은 화면에서는 컴팩트하게 예쁘게 실행되네요!!! 배우고갑니다~!!!

Comment on lines +29 to +33
const dateInputs = document
.querySelectorAll('.dateInput')
.forEach((dateInput) => {
dateInput.setAttribute('min', today);
});

Choose a reason for hiding this comment

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

시작일 설정에 대한 제한도 걸어두신거 좋은 아이디어 인것 같아요! foreach 함수를 자유롭게 사용하시는 것 같아요 저도 배워야겠어요!

Copy link

@rmdnps10 rmdnps10 left a comment

Choose a reason for hiding this comment

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

전반적으로 코드가 많이 정제되어 있다고 느꼈습니다 👍👍👍 리뷰하면서 저도 많은 자극을 받았네요 ㅎㅎ 고생하셨어요

@@ -181,3 +182,13 @@ label {
font-weight: 400 !important;
/* background-color: whitesmoke; */
}

@media (max-width: 500px) {

Choose a reason for hiding this comment

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

반응형도 고려하셨군요! 현재 코드로 미루어보아 500px 아래에서도 UI적으로 아주 깔끔할 것 같습니다! 나중에 모바일 상에서 볼 수 있는 날짜, 중요도 설정 버튼을 따로 추가할 수도 있을 것 같아요~

Copy link

@sujinRo sujinRo left a comment

Choose a reason for hiding this comment

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

안녕하세요! 프론트 운영진 노수진입니다😊

선택 구현 요소까지 열심히 구현해주신 것 같아 과제 잘 보았습니다~!
다른 분들이 리뷰를 잘 달아주셔서 쓸 내용이 따로 없네요!,, 하핫
반응형 디자인부터, 날짜, 중요도에 따른 디자인 변화까지 많은 기능들을 추가해주셔서 즐겁게 코드리뷰할 수 있었습니다!
이번 주 과제 수고하셨고, 앞으로 과제도 화이팅입니다!!

if (TODOS[i].fromDate >= todo.fromDate) break; // 시작일이 빠른 todo가 더 낲에 위치
}
}
TODOS.splice(i, 0, todo);
Copy link

Choose a reason for hiding this comment

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

그러니까요!!! 이런 추가적인 기능까지 짱이네요~!!👍

Copy link
Collaborator

@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.

안녕하세요 놀러왔다가 덕담 나누고 갑니당~~
고차함수 중간중간 사용하셨는데 좀 더 간결하거나 가독성이 좋아지는 경우도 있어서 참고만 해주셔요...

Comment on lines +17 to +19
for (const todo of TODOS) {
addNewTodoLi(todo);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이미 알고 계시겠지만 이부분에 고차함수를 써보는 것도 괜찮을 것 같아요!

Suggested change
for (const todo of TODOS) {
addNewTodoLi(todo);
}
TODOS.forEach(todo => addNewTodoLi(todo));

Comment on lines +92 to +94
if (todo.priority === 3) newLi.classList.add('high');
else if (todo.priority === 2) newLi.classList.add('mid');
else newLi.classList.add('low');
Copy link
Collaborator

Choose a reason for hiding this comment

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

혹시 이부분은 아직 작은 기능 구현이라 굳이 필요는 없을 것 같은데 이렇게 관리해도 괜찮을 것 같습니다!

Suggested change
if (todo.priority === 3) newLi.classList.add('high');
else if (todo.priority === 2) newLi.classList.add('mid');
else newLi.classList.add('low');
const priorityClassMap = {
3: 'high',
2: 'mid',
1: 'low'
};
const priorityClass = priorityClassMap[todo.priority] || 'low';
newLi.classList.add(priorityClass);

Comment on lines +132 to +141
let i;
for (i = 0; i < TODOS.length; i++) {
if (TODOS[i].idx == idx) {
TODOS[i].isDone = !TODOS[i].isDone;
break;
}
}
const todo = TODOS[i];

TODOS.splice(i, 1); // 해당 todo를 삭제한 후
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 부분도 고차함수를 이용할 수 있을 것 같아요!

Suggested change
let i;
for (i = 0; i < TODOS.length; i++) {
if (TODOS[i].idx == idx) {
TODOS[i].isDone = !TODOS[i].isDone;
break;
}
}
const todo = TODOS[i];
TODOS.splice(i, 1); // 해당 todo를 삭제한 후
const todoIndex = TODOS.findIndex((todo) => todo.idx == idx);
if (todoIndex !== -1) {
const todo = TODOS[todoIndex];
todo.isDone = !todo.isDone;
TODOS.splice(todoIndex, 1);
}

Comment on lines +148 to +150
.content {
flex-grow: 2;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

image 영어를 입력하면 넘어가서
Suggested change
.content {
flex-grow: 2;
}
.content {
flex-grow: 2;
word-break : break-all;
}

와 같이 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.

오 영어를 입력하면 저렇게 되는건 또 몰랐네요! 좀 더 다양한 케이스에 대해 테스트해봐야겠어요~~ 감사합니다!

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.

5 participants