[1주차] 박지수 미션 제출합니다.#11
Conversation
billy0904
left a comment
There was a problem hiding this comment.
전체적으로 코드를 깔끔하고 가독성 좋게 작성해주셔서 막히는 부분없이 살펴볼 수 있었습니다!👍✨
과제 하느라 수고하셨습니다! 🍀
| // 엔터키로 할 일 추가 가능 | ||
| newTodoInput.addEventListener('keydown', (e) => { | ||
| if (e.key === 'Enter') { | ||
| addTodo(); | ||
| } | ||
| }); No newline at end of file |
There was a problem hiding this comment.
배포 링크에서 투두 작성을 해보았는데 엔터 키로 투두를 추가할 경우, 위와 같이 앞선 입력의 마지막 글자가 같이 생성되는 문제를 발견했습니다!
마지막 문자가 특수문자인 경우에는 엔터가 한 번으로 인식되지만 일반문자일 경우 두 번으로 인식되는 걸 보니 아마 브라우저가 엔터의 기본 동작을 처리하고 있는 것 같아요. 저도 엔터키로 생성하는 기능을 구현했는데 엔터 키가 브라우저의 기본 동작으로 처리되어서 엔터가 두 번씩 인식된다고 하더라고요! 저는 이 글을 참고해서 e.preventDefault()로 기본 동작을 막도록 처리했습니다. 혹시 도움되실까 해서 링크 남깁니다!
| // 엔터키로 할 일 추가 가능 | |
| newTodoInput.addEventListener('keydown', (e) => { | |
| if (e.key === 'Enter') { | |
| addTodo(); | |
| } | |
| }); | |
| // 엔터키로 할 일 추가 가능 | |
| newTodoInput.addEventListener('keydown', (e) => { | |
| if (e.key === 'Enter') { | |
| e.preventDefault(); | |
| addTodo(); | |
| } | |
| }); |
There was a problem hiding this comment.
안녕하세요 가빈님!!
생각 못한 부분이었는데 참고글까지 주시고 정말 도움되는 리뷰네요🥹
| </header> | ||
|
|
||
| <main> | ||
| <section class="todo-container"> |
There was a problem hiding this comment.
섹션 태그를 사용하셔서 코드 구조가 한눈에 보이니 좋네요! 항상 컨테이너 태그에만 신경을 쓰고 section 태그는 사용해보지 않았는데 이번 기회에 배워갑니다! 👍
| addButton.addEventListener('click', addTodo); | ||
|
|
||
| function addTodo() { | ||
| const newTodo = newTodoInput.value.trim(); |
There was a problem hiding this comment.
trim() 메서드로 불필요한 공백문자를 제거하셔서 리스트가 깔끔하게 출력되니 좋네요! ✨
| button { | ||
| padding: 10px 20px; | ||
| background-color: #4caf50; | ||
| border: none; | ||
| border-radius: 5px; | ||
| cursor: pointer; | ||
| } |
There was a problem hiding this comment.
| button { | |
| padding: 10px 20px; | |
| background-color: #4caf50; | |
| border: none; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| } | |
| button { | |
| padding: 10px 20px; | |
| background-color: #4caf50; | |
| border: none; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| white-space: nowrap; | |
| } |
위와 같이 투두의 내용이 길어져서 요소의 높이와 삭제 버튼의 높이가 함께 높아질 때 "삭제" 텍스트가 그 높이에 따라 줄바꿈을 하는 현상이 있습니다. 개인적인 취향으로 일관적인 UI 제공을 위해 white-space: nowrap;으로 줄바꿈 방지를 해주시면 훨씬 예쁜 페이지가 될 것 같습니다!😊
There was a problem hiding this comment.
빌드 테스트 할 때 대부분 글 짧게 작성하고 올렸어서 몰랐는데, 이런 부분이 있었네요.
테스트 할 때 다양한 케이스로 많이 시도해야 이런 부분을 잡을 수 있는 것 같아요.
줄바꿈 방지도 새로 배워갑니다! 감사합니다😊
| #todoList li { | ||
| background-color: #2c2c2c; | ||
| padding: 10px; | ||
| border-radius: 5px; | ||
| margin-bottom: 10px; | ||
| display: flex; | ||
| justify-content: space-between; | ||
| } |
There was a problem hiding this comment.
숫자를 연속해서 입력하는 경우, 그 길이가 길어지면 줄바꿈이 일어나지 않고 칸을 뚫고 나가는(?) 현상이 있습니다! word-break: break-all; 속성을 사용하여 단어 중간이나 연속된 숫자 중간에서도 줄바꿈이 일어나도록 해주시면 좋을 것 같아요🤗
| #todoList li { | |
| background-color: #2c2c2c; | |
| padding: 10px; | |
| border-radius: 5px; | |
| margin-bottom: 10px; | |
| display: flex; | |
| justify-content: space-between; | |
| } | |
| #todoList li { | |
| background-color: #2c2c2c; | |
| padding: 10px; | |
| border-radius: 5px; | |
| margin-bottom: 10px; | |
| display: flex; | |
| justify-content: space-between; | |
| word-break: break-all; | |
| } |
There was a problem hiding this comment.
가빈님 정말 지식이 풍부하신 것 같아요. 테스트케이스도 다양하게 해보셨네요. 리뷰에서 많이 배워갑니다. 감사합니다!! 😊
There was a problem hiding this comment.
이 부분은 사실 제 과제에서도 발생한 문제라서...ㅋㅎㅎㅎ 저도 뒤늦게 발견했는데 지수 님 코드에도 같은 오류가 있어 공유해봤습니다!😶✨ 도움 되셨다면 다행이에요! 좋은 코드 감사합니다!!👍
jiwonnchoi
left a comment
There was a problem hiding this comment.
코드가 전반적으로 정말 깔끔하다는 생각이 많이 들어 저도 배우고 싶습니다🥹 또 DOM의 특성에 대해 기본적으로 잘 알고 조작하신다는게 느껴지는 코드라 인상깊었습니다! 1주차 과제하시느라 수고 많으셨어요!!🔥
| <div class="todo-input"> | ||
| <input type="text" id="newTodo" placeholder="할 일 추가"> | ||
| <button id="addButton">추가</button> | ||
| </div> |
There was a problem hiding this comment.
클래스와 id 각각에 적절한 네이밍 규칙을 잘 지켜주신 점 정말 좋은 것 같습니다! 생각해보니 저는 대부분 클래스명만 사용했어서 id도 적절히 활용해야겠다는 생각이 듭니다😂
| if (newTodo) { | ||
| const todoItem = document.createElement('li'); | ||
| const textNode = document.createTextNode(newTodo); | ||
| const removeButton = document.createElement('button'); | ||
| removeButton.textContent = '삭제'; | ||
| removeButton.addEventListener('click', () => { | ||
| todoList.removeChild(todoItem); | ||
| }); | ||
|
|
||
| todoItem.appendChild(textNode); | ||
| todoItem.appendChild(removeButton); | ||
| todoList.appendChild(todoItem); |
There was a problem hiding this comment.
노드객체를 생성하고 DOM에 연결시켜주는 작업이 굉장히 깔끔해서 DOM 개념을 정확히 이해하고 쓰신 듯해요👍👍 특히 저는 innerText를 사용했었는데 코드리뷰하면서 textContent가 css에 영향을 받지 않는다는 점에서 더 효율적임을 알게 되었는데 이 부분도 잘 고려하신 것 같아 인상적입니다!
| todoItem.appendChild(textNode); | ||
| todoItem.appendChild(removeButton); | ||
| todoList.appendChild(todoItem); |
There was a problem hiding this comment.
다른 분들 코드리뷰 보면서 저도 알게 된 것인데요, appendChild로 동일 대상에 여러 번 노드 객체를 추가하고 있는 부분을 append로 한 번에 쓰면 더 간결할 것 같습니다!
todoItem.append(textNode, removeButton);
jinnyleeis
left a comment
There was a problem hiding this comment.
지수님 이번주 과제하시느라 수고 많으셨어요!
불필요한 코드를 최소화하는 것이 어떻게보면 굉장히 어려운 부분인데, 전반적으로 불필요한 코드 없이 깔끔하게 가독성 있는 코드 작성해주신 것 같아서 좋아요!!!
현재 엔터키로 할일 추가시 중복해서 추가되는 부분을 수정하면 더욱 더 완성도가 올라갈 것 같아요!
이번 과제도 정말 수고 많으셨어요!!!
| } No newline at end of file | ||
| } | ||
| // 엔터키로 할 일 추가 가능 | ||
| newTodoInput.addEventListener('keydown', (e) => { |
There was a problem hiding this comment.
버튼 클릭시 할일이 1개씩 잘 추가되는 반면, 엔터키를 누르면 할일이 항상 2개씩 중복 추가하는 문제가 있는 것 같아요!!
문제의 원인은 'keydown' 이벤트 발생 시점 때문인 것 같은데요,
'keydown' 이벤트는 모든 키를 눌렀을때 발생하는 이벤트로, 문자/숫자/특수문자/enter 키를 눌렀을 때는 '연속적으로' 발생한다고 해요!!
이벤트 핸들러 내에 콘솔로 찍어보면 엔터키를 한번만 클릭했음에도 2번 출력되는걸 볼 수 있네요..!

지금 필요한 건 일회성 동작을 보장하는 방법인데, 이를 위해선 keydown 이벤트 말고, keyup 이벤트를 사용하는 것을 추천드려요!
keyup 이벤트는 키를 눌렀다가 뗐을 때 한 번만 발생하므로, 연속적인 이벤트 발생을 방지할 수 있어요.
keypress 이벤트도 가능하긴 하나, 공식 문서에서 '폐지'되었으므로 사용하지 않을 것으로 권장해요.
|
|
||
| function addTodo() { | ||
| const newTodo = newTodoInput.value.trim(); | ||
| if (newTodo) { |
There was a problem hiding this comment.
할일 내용이 없을 때 사용자에게 이에 대한 피드백이 없어서 UX적으로 조금 어색할 수 있을 것 같아요!
할일 없을 때, 버튼의 색을 다르게 한다거나 메시지를 띄워서 양식이 invalid함을 사용자에게 알릴 수 있으면 좋을 것 같아요!
| width: 300px; | ||
| } | ||
|
|
||
| .todo-container { |
| todoList.removeChild(todoItem); | ||
| }); | ||
|
|
||
| todoItem.appendChild(textNode); |
There was a problem hiding this comment.
appendchild()를 여러번 사용하면, dom 조작이 여러번 발생할 수 있어 성능에 그리 좋지 않다고 해요!
다른 분들 코드리뷰에도 언급한 내용이니 dom 조작을 최적화하는 documnet fragment 객체와 리플로우 리페인팅에 대해서 살펴보시면 좋을 것 같아요!

배포 링크
https://master--benevolent-snickerdoodle-3bdac0.netlify.app/
느낀점
Key Questions
document)에서 시작해, 이벤트가 발생한 요소에 도달할 때까지 하위 요소들로 전달되는 과정이다. 이때 상위 요소부터 하위 요소로 이벤트가 전파된다.addEventListener메서드의 옵션을 통해 캡처링을 사용할 수 있다.