Conversation
only1Ksy
left a comment
There was a problem hiding this comment.
안녕하세요 윤성 님! 1주차 과제 진행하시느라 고생 많으셨습니다 👍 전반적으로 구조가 깔끔하게 작성되어 이해하기 편했고, 특히 이번 과제의 KQ를 잘 반영해 코드에 녹여내신 부분이 인상적이었습니다! 몇 가지 리뷰를 남겨 보았으니 참고해 보시면 좋을 것 같습니다
| const datePicker = document.getElementById("datePicker"); | ||
| const todayEl = document.getElementById("todayLabel"); | ||
|
|
||
| const form = document.getElementById("todoForm"); |
| @@ -0,0 +1,201 @@ | |||
| // 유틸 | |||
| }); | ||
| } | ||
|
|
||
| // 리스트 이벤트 위임 |
| render(); | ||
|
|
||
| // 추가 | ||
| if (form) { |
There was a problem hiding this comment.
여기도 마찬가지로 form 요소가 없어 아래 else if 문으로만 분기처리 되고 있는 것 같습니다!
| input.addEventListener("keydown", (e) => { | ||
| if (e.key === "Enter") addFromInput(); |
There was a problem hiding this comment.
| input.addEventListener("keydown", (e) => { | |
| if (e.key === "Enter") addFromInput(); | |
| input.addEventListener("keydown", (e) => { | |
| if (e.isComposing) return; | |
| if (e.key === "Enter") addFromInput(); |
keydown 이벤트를 활용할 때, enter를 누르면 한글 중복 입력 문제가 발생할 수 있습니다! isComposing 을 활용하면 이를 방지할 수 있으니 참고해 주시면 좋을 것 같습니당
| due: currentDate, | ||
| }); | ||
| save(); | ||
| render(); |
There was a problem hiding this comment.
지금은 리스트가 하나 추가될 때마다 render()를 호출해 전체 요소를 리렌더링 하고 있는 것으로 보이는데, 새로 추가된 요소만 appendChild로 붙여 주는 방식으로 개선하면 불필요한 DOM 재생성을 줄일 수 있어 성능 측면에서 더 효율적일 것 같습니다! 삭제나 토글 로직도 같은 측면에서 개선의 여지가 있어 보입니당
| listEl.appendChild(li); | ||
| }); | ||
| const items = listEl.querySelectorAll(".todo-item"); | ||
| if (items.length > 5) { |
There was a problem hiding this comment.
딱 리스트가 다섯 개만 보이도록 높이를 동적으로 계산해 주신 부분이 디테일하네요!!👍
다만 해당 부분은 render 함수 안에 포함시키기보다는 별도의 함수로 분리하는 방식도 고려해 보시면 좋을 것 같습니당
배포링크
Review Question
1. DOM은 무엇인가요?
DOM(Document Object Model): 브라우저가 HTML 문서를 트리 구조의 객체 그래프로 표현한 모델

각 태그(요소)는 **노드(node)**가 되고, JS로 이 노드들을 찾고/만들고/지우고/속성을 바꿀 수 있다.
이번 코드를 짜면서 다음과 같이 사용됐다.
찾기: document.getElementById('todoList'), querySelector('.list-section')
생성: document.createElement('li')
수정: el.textContent = '…', el.className = 'todo-item done'
삽입/삭제: parent.appendChild(li), el.remove(), listEl.innerHTML = ""
2. 이벤트 흐름 제어(버블링 & 캡처링)이 무엇인가요?
이벤트 흐름 제어는 캡처링 → 타겟 → 버블링 의 3단계 흐름을 가진다.
과제에서 다음과 같이 적용되었다.
매 항목마다 리스너를 달지 않고, 부모 하나에만 달아 버블링으로 처리했다.
e.target은 실제 클릭된 가장 깊은 요소로 closest()을 통해 역할(버튼/체크박스/리스트 아이템)을 찾아 올라감.
3. 클로저와 스코프가 무엇인가요?
클로저(Closure): 함수 + 그 함수가 선언될 때의 스코프(환경)가 함께 저장되는 현상
->바깥 함수의 변수를 내부 함수가 기억하고 접근할 수 있게 한다.
상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용한다.
스코프(Scope): 변수에 접근 가능한 범위
1.전역 스코프(global)는 어디에서든 해당 변수에 접근 가능
2.지역 스코프(local)의 경우, 한정적인 범위에서 해당 변수에 접근이 가능(JS는 지역 스코프의 두 가지 유형 지원)
<참고자료>
DOM이란
스코프