-
Notifications
You must be signed in to change notification settings - Fork 10
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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
은 깃에 올리지 않아도 될 것 같습니다~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 프론트 운영진 배성준입니다!
첫 과제 고생하셨어요~~ 코드를 되게 깔끔하게 짜셔서 리뷰하기 편했습니다!!
함수를 작은 단위로 쪼개서 작성하셔서 가독성이 되게 좋은 것 같아요~~~~
몇가지 코멘트 달았으니 한번 참고해주시면 될 것 같아요 고생하셨습니다~~~~~
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}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
날짜 format관련해서 toLocaleDateString 사용하는 것도 괜찮을 것 같아요! 관련한 블로그 첨부하겠습니다!
newlist.appendChild(checkIcon); | ||
newlist.appendChild(todoText); | ||
newlist.appendChild(deleteIcon); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appendChild를 append를 이용하여 작성할 수도 있어요! 한번 블로그글 이것도 참고해보면 좋을 것 같아요!!!
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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alert('내용을 입력해 주세요!'); | ||
else { | ||
todolist.appendChild(createTodo(inputForm.value)); //todoList에 추가 | ||
console.log('입력'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commit할때 console.log 는 되도록 지우는게 좋아요!
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(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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(); |
중복되는 코드는 이렇게 줄일 수 있을 것 같아요!
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)); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로스 구현까지 ~~~ 최곱니다
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)); | ||
}; |
There was a problem hiding this comment.
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')에 중복해서 접근하는데 전역으로 선언 후 필요한 곳에서 사용해도 될 것 같아요!
const countDone = () => { | ||
const doneLength = document.querySelectorAll('ul#done_lists .todo-list'); | ||
const doneNum = document.querySelector('span#done_num'); | ||
|
||
doneNum.textContent = `Done : ${doneLength.length}`; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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}`; | |
}; |
와 같이 변수 이름을 지을 때 목적을 분명히 하면 좋을 것 같아요~~~
savedTodoLists.forEach(todo => { | ||
toDoList.appendChild(createTodo(todo)); | ||
}); | ||
|
||
//doneList에 있는 것들은 선을 그어서 다시 로드해야하기 때문에 줄 긋고 appendChild | ||
savedDoneLists.forEach(done => { | ||
let listItem = createTodo(done); | ||
listItem.style.textDecoration = 'line-through'; | ||
doneList.appendChild(listItem); | ||
}); |
There was a problem hiding this comment.
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 = () => { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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); | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 주석이 없었는데, 기능마다 주석이 되어있어서 읽기 편했습니다 !!! 멋져요
// 엔터키 입력이 발생하는경우 실행되는 함수 | ||
// 한글입력시 두번 실행되는것을 방지함 | ||
addTodo(toDoList); | ||
} |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
str + 'pm' 이라 이미 str타입이니까 굳이 String함수를 두번써줄 필요는 없을 것 같아요!
[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가 가장 일반적으로 사용되고 있는 프론트엔드 프로그래밍 언어이기 때문에 꼭 공부해야한다고 생각한다.
[코드에서 주석을 다는 바람직한 방법은 무엇일까요?]
코드에서 주석을 다는 목적은 다른 사람, 혹은 미래의 내가 읽었을 때 바로 코드의 의미를 알 수 있게 하는 것이라고 생각하기 때문에, 메서드 별로 주석을 달아주는 것이 중요하다고 생각한다.
또한 혹시 알아볼 수 없을만한 복잡한 코드의 경우에는 주석을 달아 설명해주는 것이 필요하다고 생각한다. 비슷한 목적으로 주석 이외에도 변수명도 알아볼 수 있도록 직관적으로 설정하는 것이 중요하다고 생각한다. 알아보기 어려운 변수명의 경우에도 주석이 필요하다고 생각한다.
하지만 너무 많은 양의 주석은 오히려 혼동을 줄 수 있으니 자제해야한다.