-
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주차] 정인영 미션 제출합니다. #7
base: master
Are you sure you want to change the base?
Conversation
html 구조와 더미데이터를 통한 css 완성
- 이벤트 리스너에 maketoDo 함수 추가하여 CREATE 구현 - 투두리스트 추가했을 때 블랙홀도 같이 밀리게 되는 버그 해결
submitHandler을 통해 로컬스토리지에 input 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.
엄청 강렬한 이미지네요ㅋㅋㅋ 시선을 확 끕니다
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.
감사합니다 😊 giphy에서 긁어왔어요!
currentTasks = filteredTasks; | ||
localStorage.setItem("currentTasks", JSON.stringify(currentTasks)); | ||
localStorage.setItem("completedTasks", JSON.stringify(completedTasks)); | ||
if (completedList.children.length > maxCompletedTasksToShow) { |
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.
완료된 task의 수에 제한을 두는건 과도하게 데이터가 쌓이지 않도록 방지하는 차원에서 좋은 것 같습니다!
근데, 성능적으로 봤을 때, element를 만들어서 list에 추가하는 과정 이후에 개수를 체크하는 것보다 해당 함수가 실행 됐을 때,
머너 체크하는 것이 더 좋을 것 같아요! 추가하고 지우는거보다 미리 검사한 후에 추가하는 과정을 스킵하는게 더 효율적이지 않을까 싶습니다ㅎㅎ
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 textElement = document.createElement("p"); | ||
textElement.innerHTML = text; | ||
const deleteImg = document.createElement("img"); | ||
deleteImg.src = "./images/delete.png"; |
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.
앞으로 디자이너와 소통하면서 logic과 view를 최대한 분리시킨 상태로 코딩을 진행하는 것이 좀 더 편하실 거라고 생각해요!
그래서, view를 담당하는 코드는 최대한 css에 맡기고, js파일에는 logic 관련 코드만 두는게 디버깅하고 업데이트 하는 데에도 좋을거에요ㅎㅎ
img src같은 경우는 각각 class를 지정해서 미리 css에 선언해두면 보기에도 좋고 로딩도 조금 더 빠를 수 있을 것이라고 생각합니다!
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.
말씀해주신 것처럼 앞으로의 디자이너와의 협업 과정에서 logic과 view를 분리하는 것은 중요한 과정인 것 같습니다 ㅎㅎ 피드백 감사합니다!
localStorage.setItem("currentTasks", JSON.stringify(currentTasks)); | ||
localStorage.setItem("completedTasks", JSON.stringify(completedTasks)); | ||
if (completedList.children.length > maxCompletedTasksToShow) { | ||
completedList.lastChild.remove(); |
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.
만약, 개수 검증을 하는걸 뒷쪽에 두는 것이 좀 더 의미있으려면, firstChild를 지워서 가장 일찍 list에 들어온 항목이 지워지고 새로운 항목이 추가되도록 하면 재밌을 것 같아요~~
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.
사실 개수 검증 코드를 작성하려다가,, 뭔가 계속 꼬여서 그만두었는데 마음을 가다듬고 로직을 찬찬히 생각해보면서 좋았을거같네요.. 감사합니다!!
resetInputText(); | ||
}; | ||
|
||
const clickHandler = (event) => { |
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.
지금은 submit handler와 clickHandler를 따로 명시해서 작성해주셨는데, 같은 기능을 하는 코드를 따로 작성하는 것보다 하나로 작성하는게 효율적일 것 같아요! 아마, 지금 html 작성된 것을 보면
태그 바깥에 button이 위치해서, click과 enter가 서로 다르게 작동하는 것 같습니다button을 form 태그 안에 위치시키면 submit event에 클릭과 엔터가 모두 반응할거에요~~ 그러면 클릭 이벤트 헨들러는 따로 작성하지 않아도 될 것 같습니다ㅎㅎ(그리고 button에 type='submit'을 지정하는게 좀 더 명시적으로 역할을 보여줄 수 있을 것 같아요!)
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.
맞습니다... 확실히 html 구조를 어떻게 설계하냐에 따라 코드 로직 구조의 효율성이 많이 다른 것 같아요, 그리고 button에 type을 명시하는 것 ㅎㅎㅎ 감사합니다!
event.target.tagName == "IMG" && | ||
event.target.src.includes("restore.png") | ||
) { | ||
const restoredTask = event.target.nextElementSibling.innerHTML; |
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.
event 객체를 통해서 dom element를 조작하는거 좋은 것 같습니다ㅎㅎ 저는 nextElementSibling 이 있는지 몰랐는데 앞으로 써먹어봐야겠네요!
placeholder="당신의 할 일을 별을 먹어치우는 블랙홀처럼 모두 해치우세요." | ||
/> | ||
</form> | ||
<button>Enter</button> |
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.
이 버튼을 form 안에 옮기면 click과 submit이 모두 submit으로 인식될거에요~
const loadCompletedTasks = (item) => { | ||
const storedCompletedTasks = localStorage.getItem(item); | ||
const parsedCompletedTasks = JSON.parse(storedCompletedTasks); | ||
parsedCompletedTasks.forEach((completedTask) => { |
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.
js의 iteration 방법을 잘 이용하신 것 같습니다~~
) { | ||
const deletedTask = | ||
event.target.nextElementSibling.nextElementSibling.innerHTML; | ||
const filteredCompletedTasks = completedTasks.filter( |
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.
filter method를 통해서 delete와 completed 구분하신 것 잘하신 것 같습니다~~
table { | ||
border-collapse: collapse; | ||
border-spacing: 0; | ||
} |
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.
reset.css를 사용하여 디폴트 스타일을 초기화한다는 개념을 처음 알았네요!! 한 수 배워갑니다👍
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.
semantic tag를 사용하여 페이지를 구성해서 훨씬 가독성이 좋은거 같습니다! 저도 다음에는 사용해보겠습니다 ㅎㅎ
background: radial-gradient( | ||
50% 50% at 50% 50%, | ||
rgba(18, 18, 18, 0) 0%, | ||
#202020 100% | ||
); |
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.
radial-gradient 사용해서 그라데이션 준 디테일이 좋네요 :)
const loadTasks = (item) => { | ||
const storedTasks = localStorage.getItem(item); | ||
const parsedTasks = JSON.parse(storedTasks); | ||
parsedTasks.forEach((task) => { | ||
addTaskToList(task); | ||
}); | ||
}; | ||
|
||
const loadCompletedTasks = (item) => { | ||
const storedCompletedTasks = localStorage.getItem(item); | ||
const parsedCompletedTasks = JSON.parse(storedCompletedTasks); | ||
parsedCompletedTasks.forEach((completedTask) => { | ||
addCompletedTaskToList(completedTask); | ||
}); | ||
}; |
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.
코드 전체적으로 Task와 CompletedTask에 대한 함수로 기능이 확실하게 구분돼있어서 굉장히 좋습니다!
listItem.appendChild(deleteImg); | ||
listItem.appendChild(restoreImg); | ||
listItem.appendChild(textElement); |
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.
저도 똑같이 피드백 받은 부분인데 append() 메서드를 사용해서 child를 한번에 append하는 방식을 사용해도 좋을 것 같아요~!
listItem.appendChild(deleteImg); | |
listItem.appendChild(restoreImg); | |
listItem.appendChild(textElement); | |
listItem.append(deleteImg, restoreImg, textElement); |
}; | ||
|
||
const addTaskToList = (text) => { | ||
if (!currentTasks.includes(text)) { |
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.
includes 메서드 사용해서 task의 중복이 없도록 예외처리한게 인상 깊습니다!
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.
안녕하세요! 프론트 운영진 노수진입니다😊
선택 구현 요소까지 열심히 구현해주신 것 같아 과제 잘 보았습니다~!
디자인에 신경쓰신 것이 느껴지는 과제였고, 그래서 더 즐겁게 코드리뷰를 할 수 있었던 것 같습니다~!
이번 주 과제 수고하셨고, 앞으로 과제도 화이팅입니다!!
event.preventDefault(); | ||
const taskText = event.target.previousElementSibling.children[0].value; | ||
if (taskText.length < 3) { | ||
alert("3글자 이상 입력하세요."); |
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.
글자 수를 이용해서 3글자 이상일 때, alert 창이 나오도록 해주셨는데,
input에 스페이스 바를 3번 누르고 엔터를 누르면 입력이 그대로 들어가요!
trim()을 이용해서 양쪽 공백을 없앤 뒤, 3글자 이상일 때, alert 창이 나오도록 해주면 좋을 것 같아요!!
listItem.innerHTML = text; | ||
currentTasks.push(text); | ||
taskList.appendChild(listItem); | ||
if (!currentTasks.includes(text)) { |
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.
이미 같은 일을 할 일에 적어두었을 때는 추가되지 않도록 해두었군요!!! 디테일이 너무 좋아요~~👍
@@ -128,6 +144,7 @@ const completedTaskClickHandler = (event) => { | |||
}; | |||
|
|||
taskForm.addEventListener("submit", submitHandler); | |||
submitButton.addEventListener("click", clickHandler); | |||
taskList.addEventListener("click", taskClickHandler); |
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.
📑 배포링크
UniverseToDo
✔️ 기능구현
🤔 느낀 점
순수 자바스크립트만으로 웹사이트를 빌딩하는 게 정말 어렵구나 하는 생각이 들었습니다... (예전 개발자들 존경..) 특히 엔터를 눌렀는데 리스트에 두개가 저장이 된다거나 하는 버그들을 맞닥뜨리면서, 아직 제가 이벤트 핸들러와 리스너의 사용에 많이 부족하다는 것을 느꼈고 이번 과제를 통하여 다시금 상기를 하게 되었던 것 같습니다. 또 그전까지는 별 생각 없이 커밋을 올렸는데 커밋 컨벤션에 맞춰 기능 구현할때마다 커밋을 올리려고 하니 어떻게 커밋을 해야 할 지 많이 고민이 들었던 것 같습니다.
⍰ Key Questions
DOM은 무엇인가요?
DOM은 문서 객체 모델의 약어인데, 브라우저가 웹 페이지를 인식하는 방식을 트리 구조로 계층화시켜 프로그래밍 방식으로 조작하게 해주는 API입니다. 트리 구조의 최상단에는 document 객체가 있고, 이 객체를 통하여 DOM 트리의 여러 노드에 접근할 수 있습니다. 이번 과제에서는 Vanilla JS를 통하여 DOM을 조작하여 클릭, 엔터와 같은 이벤트를 처리했습니다.
HTML (tag) Element를 JavaScript로 생성하는 방법은 어떤 것이 있고, 어떤 방법이 가장 적합할까요?
이번 과제에 Element를 생성할 때 사용한 DOM API는 .createElement()였는데, innerHTML()과 insertAdjacent() 와 비교했을 때 생성한 요소를 삽입하는 추가 코드가 필요하여 번거로운 부분이 있으나 이번 과제에서 DOM 트리 구조가 그렇게 복잡하지 않아 사용하였습니다.
하지만 이런 간단한 작업에도 상대적으로 코드가 길어져, 아무래도 일반적인 프로젝트에서는 리액트, 뷰 같은 라이브러리를 사용하는 게 좋을 것 같습니다.
Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?
Semantic tag는 "의미가 있는 태그" 라는 뜻으로 header, nav, main, footer, article, section 등이 있습니다. 이러한 시멘틱 태그를 적절히 사용하면, 키워드를 통한 검색결과에 잘 노출되게 할 수 있고, 페이지 탐색에 도움을 줄 수 있습니다.
개인적으로 느꼈던 시멘틱 태그의 큰 장점은 html의 구조를 설계할 때, 시멘틱 태그를 통해 설계하면 좀 더 코드 가독성이 늘었던 것이었습니다.
Flexbox Layout은 무엇이며, 어떻게 사용하나요?
Flexbox layout 은 요소를 가로 정렬할 때는 물론 요소의 배치와 정렬하는 데 사용되는 CSS 레이아웃 모델입니다.
기본적으로 정렬할 요소의 부모 요소에다가 display: flex 를 부여해주어 Flexbox layout을 개시하게 됩니다. 기호에 따라 부모 요소에 justify-content, align-items, flex-wrap 와 같은 속성들을 정의해주고, 자식 요소에선 align-self, flex-grow 와 같은 속성들을 정의하여 정렬을 반응형으로 어렵지 않게 구현하는데 정말 유용하게 쓰이는 것 같습니다.
JavaScript가 다른 언어들에 비해 주목할 만한 점에는 어떤 것들이 있나요?
이번에 학교 수업에서 프론트, 백엔드, DB를 모두 자바스크립트만으로 구현하는 법을 배우고 있는데 (React, Express, MySQL) 이처럼 하나의 언어로 모든 분야를 조작할 수 있다는 점에서 자바스크립트는 굉장히 자유도가 높으며 활용도가 높은 언어인 것 같고, 앞으로도 수많은 프레임워크와 라이브러리가 나올 것 같습니다.
코드가 복잡성이 높아질수록 보다 핵심적인 부분만 주석을 다는 게 좋은 것 같습니다.