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주차] 박지수 미션 제출합니다. #11

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

Conversation

jsomnium
Copy link

@jsomnium jsomnium commented Sep 7, 2024

배포 링크

https://master--benevolent-snickerdoodle-3bdac0.netlify.app/

느낀점

  • DOM 이 뭔지 몰라서 처음에는 개념만 검색하고 이해가 안가서 어려웠습니다. 근데 설명을 쭉 읽다 보니까 생각보다 쉬운 개념이라서 쉽게 진행할 수 있었습니다.
  • 주석도 잘 쓰고 커밋도 기능별로 확실히 분리해서 하고 싶었는데 습관이 있다 보니까 마음대로 되진 않더라구요 ㅠ 이번엔 그냥 첫 번째 단계라고 생각하고 다음 주차에는 더 제대로 해보고 싶습니다.
  • React 안쓰니까 생각보다 불편한 점이 있네요... js에 대한 이해가 아직 부족한 것 같습니다. 함수 동작 방식도 아직 더 공부해야 할 것 같고, 다음번에는 검색의 힘을 빌리지 않고 스스로 함수를 짜는 도전을 해보고 싶네요. 이번에 그래도 기능들은 다 동작하게 만들어서 나름 뿌듯합니다.
  • Key Question 에 대해서 깊게 공부하기 보다는 일단 알아가는 과정이라고 생각하고 클로저, 스코프에 대해서는 깊게 이해하지 못한 것 같습니다. 개념부터 살짝 어렵게 느껴져서, 이번 과제 마무리하고 다시 공부해야 할 것 같습니다.

Key Questions

  • DOM은 무엇인가요?
    • DOM(Document Object Model)은 HTML 문서를 객체로 표현한 구조다. 이를 통해 웹 페이지의 노드를 수정하거나 추가할 수 있다. DOM은 계층 구조를 이루며, 이를 DOM 트리라고 부른다. DOM 트리에서 각 객체는 '노드'라고 하며, 노드는 부모, 자식, 형제 관계를 가진다. HTML 태그는 '요소 노드', 텍스트는 '텍스트 노드'로 구분된다.
  • 이벤트 흐름 제어(버블링 & 캡처링)이 무엇인가요?
    • 이벤트 흐름 제어는 웹 브라우저에서 이벤트가 발생했을 때 그 이벤트가 DOM 트리를 따라 전달되는 방식을 말한다. 크게 캡처링(Capturing)과 버블링(Bubbling) 두 가지 단계가 있다.
      1. 캡처링(Capturing): 이벤트가 최상위 요소(주로 document)에서 시작해, 이벤트가 발생한 요소에 도달할 때까지 하위 요소들로 전달되는 과정이다. 이때 상위 요소부터 하위 요소로 이벤트가 전파된다.
      2. 버블링(Bubbling): 캡처링 단계가 끝난 후, 이벤트가 발생한 요소에서 다시 상위 요소로 전달되는 과정이다. 즉, 하위 요소에서 상위 요소로 이벤트가 전파된다.
    • 기본적으로 웹 브라우저는 버블링을 사용하지만, addEventListener 메서드의 옵션을 통해 캡처링을 사용할 수 있다.
  • 클로저와 스코프가 무엇인가요?
    • 스코프는 변수나 함수에 접근할 수 있는 유효 범위를 말한다. 자바스크립트에서는 주로 두 가지 스코프가 있다.
      • 전역 스코프(Global Scope): 코드의 모든 부분에서 접근 가능한 범위이다. 전역에 선언된 변수는 어디에서든 사용할 수 있다.
      • 지역 스코프(Local Scope): 함수나 블록 내부에서 선언된 변수들이 해당 범위 안에서만 유효하다. 즉, 함수 내에서 선언된 변수는 함수 외부에서는 접근할 수 없다.
    • 클로저는 외부 함수의 변수에 접근할 수 있는 내부 함수를 말한다. 클로저는 함수가 생성될 때 외부 스코프의 변수를 기억하여, 그 함수가 실행되는 시점에도 해당 변수에 접근할 수 있게 한다.
      • 클로저는 함수 내부에서 정의된 함수가 외부 함수의 변수에 접근할 수 있는 능력 때문에 매우 강력하며, 특히 비동기적 작업이나 데이터를 캡슐화하는 데 유용하다.

Copy link

@billy0904 billy0904 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 +32 to +37
// 엔터키로 할 일 추가 가능
newTodoInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
addTodo();
}
});

Choose a reason for hiding this comment

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

Screen Shot 2024-09-08 at 6 29 04 PM

배포 링크에서 투두 작성을 해보았는데 엔터 키로 투두를 추가할 경우, 위와 같이 앞선 입력의 마지막 글자가 같이 생성되는 문제를 발견했습니다!

마지막 문자가 특수문자인 경우에는 엔터가 한 번으로 인식되지만 일반문자일 경우 두 번으로 인식되는 걸 보니 아마 브라우저가 엔터의 기본 동작을 처리하고 있는 것 같아요. 저도 엔터키로 생성하는 기능을 구현했는데 엔터 키가 브라우저의 기본 동작으로 처리되어서 엔터가 두 번씩 인식된다고 하더라고요! 저는 이 글을 참고해서 e.preventDefault()로 기본 동작을 막도록 처리했습니다. 혹시 도움되실까 해서 링크 남깁니다!

Suggested change
// 엔터키로 할 일 추가 가능
newTodoInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
addTodo();
}
});
// 엔터키로 할 일 추가 가능
newTodoInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
addTodo();
}
});

Copy link
Author

Choose a reason for hiding this comment

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

안녕하세요 가빈님!!
생각 못한 부분이었는데 참고글까지 주시고 정말 도움되는 리뷰네요🥹

</header>

<main>
<section class="todo-container">

Choose a reason for hiding this comment

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

섹션 태그를 사용하셔서 코드 구조가 한눈에 보이니 좋네요! 항상 컨테이너 태그에만 신경을 쓰고 section 태그는 사용해보지 않았는데 이번 기회에 배워갑니다! 👍

addButton.addEventListener('click', addTodo);

function addTodo() {
const newTodo = newTodoInput.value.trim();

Choose a reason for hiding this comment

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

trim() 메서드로 불필요한 공백문자를 제거하셔서 리스트가 깔끔하게 출력되니 좋네요! ✨

Comment on lines +70 to +76
button {
padding: 10px 20px;
background-color: #4caf50;
border: none;
border-radius: 5px;
cursor: pointer;
}

Choose a reason for hiding this comment

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

Screen Shot 2024-09-08 at 7 19 17 PM
Suggested change
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;으로 줄바꿈 방지를 해주시면 훨씬 예쁜 페이지가 될 것 같습니다!😊

Copy link
Author

Choose a reason for hiding this comment

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

빌드 테스트 할 때 대부분 글 짧게 작성하고 올렸어서 몰랐는데, 이런 부분이 있었네요.
테스트 할 때 다양한 케이스로 많이 시도해야 이런 부분을 잡을 수 있는 것 같아요.
줄바꿈 방지도 새로 배워갑니다! 감사합니다😊

Comment on lines +48 to +55
#todoList li {
background-color: #2c2c2c;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
}
Copy link

@billy0904 billy0904 Sep 8, 2024

Choose a reason for hiding this comment

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

Screen Shot 2024-09-08 at 7 40 12 PM

숫자를 연속해서 입력하는 경우, 그 길이가 길어지면 줄바꿈이 일어나지 않고 칸을 뚫고 나가는(?) 현상이 있습니다! word-break: break-all; 속성을 사용하여 단어 중간이나 연속된 숫자 중간에서도 줄바꿈이 일어나도록 해주시면 좋을 것 같아요🤗

Suggested change
#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;
}

Copy link
Author

@jsomnium jsomnium Sep 8, 2024

Choose a reason for hiding this comment

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

가빈님 정말 지식이 풍부하신 것 같아요. 테스트케이스도 다양하게 해보셨네요. 리뷰에서 많이 배워갑니다. 감사합니다!! 😊

Choose a reason for hiding this comment

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

이 부분은 사실 제 과제에서도 발생한 문제라서...ㅋㅎㅎㅎ 저도 뒤늦게 발견했는데 지수 님 코드에도 같은 오류가 있어 공유해봤습니다!😶✨ 도움 되셨다면 다행이에요! 좋은 코드 감사합니다!!👍

Copy link

@jiwonnchoi jiwonnchoi left a comment

Choose a reason for hiding this comment

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

코드가 전반적으로 정말 깔끔하다는 생각이 많이 들어 저도 배우고 싶습니다🥹 또 DOM의 특성에 대해 기본적으로 잘 알고 조작하신다는게 느껴지는 코드라 인상깊었습니다! 1주차 과제하시느라 수고 많으셨어요!!🔥

Comment on lines +27 to +30
<div class="todo-input">
<input type="text" id="newTodo" placeholder="할 일 추가">
<button id="addButton">추가</button>
</div>

Choose a reason for hiding this comment

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

클래스와 id 각각에 적절한 네이밍 규칙을 잘 지켜주신 점 정말 좋은 것 같습니다! 생각해보니 저는 대부분 클래스명만 사용했어서 id도 적절히 활용해야겠다는 생각이 듭니다😂

Comment on lines +16 to +27
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);

Choose a reason for hiding this comment

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

노드객체를 생성하고 DOM에 연결시켜주는 작업이 굉장히 깔끔해서 DOM 개념을 정확히 이해하고 쓰신 듯해요👍👍 특히 저는 innerText를 사용했었는데 코드리뷰하면서 textContent가 css에 영향을 받지 않는다는 점에서 더 효율적임을 알게 되었는데 이 부분도 잘 고려하신 것 같아 인상적입니다!

Comment on lines +25 to +27
todoItem.appendChild(textNode);
todoItem.appendChild(removeButton);
todoList.appendChild(todoItem);

Choose a reason for hiding this comment

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

다른 분들 코드리뷰 보면서 저도 알게 된 것인데요, appendChild로 동일 대상에 여러 번 노드 객체를 추가하고 있는 부분을 append로 한 번에 쓰면 더 간결할 것 같습니다!

todoItem.append(textNode, removeButton);

Copy link
Collaborator

@jinnyleeis jinnyleeis left a comment

Choose a reason for hiding this comment

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

지수님 이번주 과제하시느라 수고 많으셨어요!
불필요한 코드를 최소화하는 것이 어떻게보면 굉장히 어려운 부분인데, 전반적으로 불필요한 코드 없이 깔끔하게 가독성 있는 코드 작성해주신 것 같아서 좋아요!!!
현재 엔터키로 할일 추가시 중복해서 추가되는 부분을 수정하면 더욱 더 완성도가 올라갈 것 같아요!

이번 과제도 정말 수고 많으셨어요!!!

jsomnium/todo.js Outdated
}
// 엔터키로 할 일 추가 가능
newTodoInput.addEventListener('keydown', (e) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

image

버튼 클릭시 할일이 1개씩 잘 추가되는 반면, 엔터키를 누르면 할일이 항상 2개씩 중복 추가하는 문제가 있는 것 같아요!!
문제의 원인은 'keydown' 이벤트 발생 시점 때문인 것 같은데요,
'keydown' 이벤트는 모든 키를 눌렀을때 발생하는 이벤트로, 문자/숫자/특수문자/enter 키를 눌렀을 때는 '연속적으로' 발생한다고 해요!!
이벤트 핸들러 내에 콘솔로 찍어보면 엔터키를 한번만 클릭했음에도 2번 출력되는걸 볼 수 있네요..!
image

지금 필요한 건 일회성 동작을 보장하는 방법인데, 이를 위해선 keydown 이벤트 말고, keyup 이벤트를 사용하는 것을 추천드려요!
keyup 이벤트는 키를 눌렀다가 뗐을 때 한 번만 발생하므로, 연속적인 이벤트 발생을 방지할 수 있어요.

keypress 이벤트도 가능하긴 하나, 공식 문서에서 '폐지'되었으므로 사용하지 않을 것으로 권장해요.

jsomnium/todo.js Outdated

function addTodo() {
const newTodo = newTodoInput.value.trim();
if (newTodo) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

할일 내용이 없을 때 사용자에게 이에 대한 피드백이 없어서 UX적으로 조금 어색할 수 있을 것 같아요!
할일 없을 때, 버튼의 색을 다르게 한다거나 메시지를 띄워서 양식이 invalid함을 사용자에게 알릴 수 있으면 좋을 것 같아요!

width: 300px;
}

.todo-container {
Copy link
Collaborator

Choose a reason for hiding this comment

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

image 투두 리스트가 컨테이너를 초과하는 것에 대한 오버 플로우 처리가 되어있지 않은 것 같아요! overflow 속성을 사용해서 할일이 컨테이너 밖을 삐져나오지 않도록 처리하면 좋을 것 같아요!

jsomnium/todo.js Outdated
todoList.removeChild(todoItem);
});

todoItem.appendChild(textNode);
Copy link
Collaborator

Choose a reason for hiding this comment

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

appendchild()를 여러번 사용하면, dom 조작이 여러번 발생할 수 있어 성능에 그리 좋지 않다고 해요!
다른 분들 코드리뷰에도 언급한 내용이니 dom 조작을 최적화하는 documnet fragment 객체와 리플로우 리페인팅에 대해서 살펴보시면 좋을 것 같아요!

#4 (comment)

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.

4 participants