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주차] 노이진 미션 제출합니다. #5

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

Conversation

leejin-rho
Copy link
Member

@leejin-rho leejin-rho commented Sep 15, 2023

[1주차]

바닐라 자바스크립트를 많이 해본 경험이 없어서 조금 헷갈리기도 했지만 열심히 해보았습니다...!
그리고 마음대로 만들어보니까 디자이너의 중요성을 더욱 알게되었습니다.
그리고 그 전에는 getElementById와 querySelector를 그냥 마음대로 사용했는데, 알아보니 getElementById()은 주어진 ID 값으로 단일 Element 객체(요소)을 가져오고, querySelector()은 CSS 선택자로 맞는 첫 번째 Element 객체(요소)을 가져오기때문에 상황에 따라 맞춰서 사용하려고 했습니다.
다음 과제에는 더 깔끔한 코드를 작성하고 싶어요...

[배포링크]

vanilla-todo-18th

[Key Questions]

[DOM은 무엇인가요?]
DOM은 Document Object Model의 약자이다. 각각의 요소는 노드(Node)라고 부르며, 서로 계층적인 관계를 가지고 있다. 화면을 나타낼 때 브라우저는 레이아웃,css tree를 가지고 render tree를 만들고 이를 실제로 나타내는 Painting과정을 가진다. 이 때 이 과정은 화면이 변화가 생길 때마다 진행되는데, 따라서 상태 변화가 많이 생기고 update되는 요소들이 많아질 수록, reflow(레이아웃과정), repaint(페인팅과정)이 다시 일어나는데 이는 화면이 느리게 나타나게 하고 로딩이 생기게 한다.
react의 경우에는 virtual dom을 이용해 표현하고, 업데이트된 내용을 한번에 real dom에 전달하기 때문에 reflow, repaint를 줄여 로딩이 거의 없이 화면이 나타날 수 있게 한다.

[HTML (tag) Element를 JavaScript로 생성하는 방법은 어떤 것이 있고, 어떤 방법이 가장 적합할까요?]
일반적으로 가장 많이 사용되는 방법은 document.createElement()이다. 이번 과제의 경우에도 새로운 리스트를 생성하기 위해서 사용했다.
또한, 템플릿 리터럴(template literal)을 사용하여 HTML 문자열을 동적으로 생성한 후 innerHTML 속성을 이용해 해당 HTML을 삽입하는 방법도 있다.
일반적으로 createElement(), appendChild()을 사용하는 것이 Element객체를 직접 생성하고 조작하기 더 편하다고 생각해서 이 방법이 더 적합하다고 생각한다.

[Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?]
Semantic tag란 웹 문서의 구조와 의미를 명확하게 전달하기 위해 HTML5에서 추가된 태그들을 말한다. Semantic tag는 웹 페이지의 구조와 의미가 명확해서 알아보기 쉽다. 그리고 기본 스타일링 및 관련 CSS 클래스(class)가 되기 때문에 스타일링이 용이하다. semantic 태그들을 사용하면 코드를 알아보기 더 쉽기 때문에 유지보수에도 용이하다.

[Flexbox Layout은 무엇이며, 어떻게 사용하나요?]
Flexbox는 부모 요소 안의 자식 요소가 더 유연하게 정렬할 수 있도록 해준다.
Flexbox는 화면 크기 변화에 따라 유동적인 레이아웃 조정이 가능해서 반응형 디자인 구현 시 용이하다. Flexbox는 다양한 정렬 및 배치 기능을 제공해 복잡한 레이아웃 설계도 가능하게 해준다. 또한 Flexbox는 아주 간단하게 아이템들을 수직/수평 중앙에 위치시킬 수 있다.

[JavaScript가 다른 언어들에 비해 주목할 만한 점에는 어떤 것들이 있나요?]
JavaScript는 웹 페이지 상에서 다양한 인터랙션이 가능하다. JavaScript는 모든 웹 브라우저에서 지원되며 Node.js와 같은 서버 사이드 환경까지 확장되어 범용 프로그래밍 언어로 널리 사용된다. 그리고 JavaScript가 가장 일반적으로 사용되고 있는 프론트엔드 프로그래밍 언어이기 때문에 꼭 공부해야한다고 생각한다.

[코드에서 주석을 다는 바람직한 방법은 무엇일까요?]
코드에서 주석을 다는 목적은 다른 사람, 혹은 미래의 내가 읽었을 때 바로 코드의 의미를 알 수 있게 하는 것이라고 생각하기 때문에, 메서드 별로 주석을 달아주는 것이 중요하다고 생각한다.
또한 혹시 알아볼 수 없을만한 복잡한 코드의 경우에는 주석을 달아 설명해주는 것이 필요하다고 생각한다. 비슷한 목적으로 주석 이외에도 변수명도 알아볼 수 있도록 직관적으로 설정하는 것이 중요하다고 생각한다. 알아보기 어려운 변수명의 경우에도 주석이 필요하다고 생각한다.
하지만 너무 많은 양의 주석은 오히려 혼동을 줄 수 있으니 자제해야한다.

Copy link
Member

@moong23 moong23 left a comment

Choose a reason for hiding this comment

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

커밋된 파일이 너무 많아서 에러가 나는 것 같습니다 ㅠㅠ
참고자료 참고하셔서 .gitignore파일을 통해
node_modules, .DS_Store은 깃에 올리지 않아도 될 것 같습니다~!

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 +4 to +11
const days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
const date = new Date();
const year = String(date.getFullYear());
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dayName = days[date.getDay()];

dateElm.innerText = `${year}-${month}-${day} ${dayName}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

날짜 format관련해서 toLocaleDateString 사용하는 것도 괜찮을 것 같아요! 관련한 블로그 첨부하겠습니다!

Comment on lines +39 to +41
newlist.appendChild(checkIcon);
newlist.appendChild(todoText);
newlist.appendChild(deleteIcon);
Copy link
Collaborator

Choose a reason for hiding this comment

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

appendChild를 append를 이용하여 작성할 수도 있어요! 한번 블로그글 이것도 참고해보면 좋을 것 같아요!!!

Comment on lines +27 to +30
let newlist = document.createElement('div'); //버튼 누르면 div 추가
let todoText = document.createTextNode(todoInput);
let checkIcon = document.createElement('span'); // check icon
let deleteIcon = document.createElement('span'); // delete icon
Copy link
Collaborator

Choose a reason for hiding this comment

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

재선언을 하지않는 변수에 대해선 const를 사용해서 선언하는게 좋을 것 같아요

};

const addTodo = todolist => {
if (!inputForm.value)
Copy link
Collaborator

Choose a reason for hiding this comment

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

빈 값 처리해주신 것 좋지만 공백을 입력했을 때 처리가 안되어 있어서 아래와 같이 공백을 todo로 설정할 수 있어요! trim()을 사용해보는거는 어떠신가요??
image

Suggested change
if (!inputForm.value)
if (!inputForm.value.trim())

alert('내용을 입력해 주세요!');
else {
todolist.appendChild(createTodo(inputForm.value)); //todoList에 추가
console.log('입력');
Copy link
Collaborator

Choose a reason for hiding this comment

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

commit할때 console.log 는 되도록 지우는게 좋아요!

Comment on lines +67 to +79
if (todolist.parentNode === toDoList) {
doneList.appendChild(todolist);
todolist.style.textDecoration = 'line-through';
saveTodos();
countTodo(); //리스트 개수를 다시 세고 숫자 바꿔줌
countDone();
} else if (todolist.parentNode === doneList) {
toDoList.appendChild(todolist);
todolist.style.textDecoration = 'none';
saveTodos();
countTodo();
countDone();
}
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 (todolist.parentNode === toDoList) {
doneList.appendChild(todolist);
todolist.style.textDecoration = 'line-through';
saveTodos();
countTodo(); //리스트 개수를 다시 세고 숫자 바꿔줌
countDone();
} else if (todolist.parentNode === doneList) {
toDoList.appendChild(todolist);
todolist.style.textDecoration = 'none';
saveTodos();
countTodo();
countDone();
}
if (todolist.parentNode === toDoList) {
doneList.appendChild(todolist);
todolist.style.textDecoration = 'line-through';
} else if (todolist.parentNode === doneList) {
toDoList.appendChild(todolist);
todolist.style.textDecoration = 'none';
}
saveTodos();
countTodo();
countDone();

중복되는 코드는 이렇게 줄일 수 있을 것 같아요!

Comment on lines +97 to +104
const saveTodos = () => {
const todoLists = Array.from(document.querySelectorAll('ul#todo_lists .todo-list')).map(list => list.textContent);
const doneLists = Array.from(document.querySelectorAll('ul#done_lists .todo-list')).map(list => list.textContent);

//문자열로 변환 후 local storage에 저장
localStorage.setItem('todoLists', JSON.stringify(todoLists));
localStorage.setItem('doneLists', JSON.stringify(doneLists));
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

로스 구현까지 ~~~ 최곱니다

Comment on lines +89 to +104
const countDone = () => {
const doneLength = document.querySelectorAll('ul#done_lists .todo-list');
const doneNum = document.querySelector('span#done_num');

doneNum.textContent = `Done : ${doneLength.length}`;
};

//local storage용 함수
const saveTodos = () => {
const todoLists = Array.from(document.querySelectorAll('ul#todo_lists .todo-list')).map(list => list.textContent);
const doneLists = Array.from(document.querySelectorAll('ul#done_lists .todo-list')).map(list => list.textContent);

//문자열로 변환 후 local storage에 저장
localStorage.setItem('todoLists', JSON.stringify(todoLists));
localStorage.setItem('doneLists', JSON.stringify(doneLists));
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

두 함수에서 document.querySelectorAll('ul#todo_lists .todo-list')에 중복해서 접근하는데 전역으로 선언 후 필요한 곳에서 사용해도 될 것 같아요!

Comment on lines +89 to +94
const countDone = () => {
const doneLength = document.querySelectorAll('ul#done_lists .todo-list');
const doneNum = document.querySelector('span#done_num');

doneNum.textContent = `Done : ${doneLength.length}`;
};
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
const countDone = () => {
const doneLength = document.querySelectorAll('ul#done_lists .todo-list');
const doneNum = document.querySelector('span#done_num');
doneNum.textContent = `Done : ${doneLength.length}`;
};
const countDone = () => {
const doneElement= document.querySelectorAll('ul#done_lists .todo-list');
const doneNumElement = document.querySelector('span#done_num');
const doneLength = doneElement.length
doneNumElement .textContent = `Done : ${doneLength}`;
};

와 같이 변수 이름을 지을 때 목적을 분명히 하면 좋을 것 같아요~~~

Comment on lines +112 to +121
savedTodoLists.forEach(todo => {
toDoList.appendChild(createTodo(todo));
});

//doneList에 있는 것들은 선을 그어서 다시 로드해야하기 때문에 줄 긋고 appendChild
savedDoneLists.forEach(done => {
let listItem = createTodo(done);
listItem.style.textDecoration = 'line-through';
doneList.appendChild(listItem);
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

고차함수 활용을 되게 잘 하시는 것 같아요!!!!!!!!!!!!!!!!!!

localStorage.setItem('doneLists', JSON.stringify(doneLists));
};

const loadTodos = () => {

Choose a reason for hiding this comment

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

||[] 를 통해 null 일 때의 경우를 고려해 에러가 나지 않게 한 것 좋아요 배워갑니다 !!


newlist.appendChild(checkIcon);
newlist.appendChild(todoText);
newlist.appendChild(deleteIcon);

Choose a reason for hiding this comment

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

저도 이렇게 했지만 코드 리뷰 해 주시는 것 보면서 배워가요

listItem.style.textDecoration = 'line-through';
doneList.appendChild(listItem);
});
};

Choose a reason for hiding this comment

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

저는 주석이 없었는데, 기능마다 주석이 되어있어서 읽기 편했습니다 !!! 멋져요

// 엔터키 입력이 발생하는경우 실행되는 함수
// 한글입력시 두번 실행되는것을 방지함
addTodo(toDoList);
}

Choose a reason for hiding this comment

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

한글이 두 번 입력되는 것을 저도 경험했는데, 방지하는 것을 배워가요 감사합니닷

deleteIcon.classList.add('todo-delete', 'fa-solid', 'fa-trash');
newlist.classList.add('todo-list');

deleteIcon.onclick = () => deleteTodo(deleteIcon);

Choose a reason for hiding this comment

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

여러 이벤트를 추가할 경우를 고려한다면 addEventListner를 사용하는 것도 좋을 것 같아요! 참고글 올립니당 https://beforb.tistory.com/37

minutes = String(String(date.getMinutes()).padStart(2, '0') + ' am');
} else {
hours = String(hour - 12).padStart(2, '0');
minutes = String(String(date.getMinutes()).padStart(2, '0') + ' pm');

Choose a reason for hiding this comment

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

str + 'pm' 이라 이미 str타입이니까 굳이 String함수를 두번써줄 필요는 없을 것 같아요!

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