-
Notifications
You must be signed in to change notification settings - Fork 11
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주차] 권동욱 미션 제출합니다. #4
base: main
Are you sure you want to change the base?
Conversation
default settings with node_modules dir
Add prettier and vite package
Add readme
add html code
add placeholder, add/remove text, ...
feature about load/save data from local storage
feature about handling todo, add, remove, and toggle(check)
page render
structure code, initialization
week 1 emoji
meyer's reset
add main division Ref: CEOS-Developers#9
add class in order to distinguish each element Ref: CEOS-Developers#8, CEOS-Developers#9
delete line-through style when checked, will be added to css Resolved: CEOS-Developers#8
Ref: #13
Remove class of individual, fine-grained elements Resolves: #13
Ref: #11
simple file structure
#todo-form span { | ||
flex-shrink: 0; | ||
font-size: var(--font-size-xxl); | ||
width: var(--button-size); | ||
height: var(--button-size); | ||
cursor: pointer; | ||
} |
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.
이모지에 cursor pointer 속성을 주신 이유가 있을까요?
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.
이 부분은 별다른 이유가 없는 것 같습니다 ,, 실수인 것 같네요 ㅠㅜ
#todo-form button, | ||
.todo 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.
css변수나 상수를 체계적으로 활용하시는 면에서 전체적으로 재사용성과 유지보수에 신경 쓴 프로젝트 구조라는 생각이 듭니다! 이 버튼의 경우에도 저라면 그냥 button 태그 속성으로 css를 설정했을 것 같은데요, 이렇게 각각의 버튼에 대해 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.
네 이번 프로젝트가 큰 볼륨을 가지고 있지는 않지만, 처음부터 습관을 들이고 싶어서 #todo-form > button / .todo > button 이런 식으로 선언하여 사용했습니다! class 추가적으로 줘서 css 설정하는 방식도 괜찮을 것 같습니다 (이 부분은 제가 괜찮은 class 이름이 생각이 안나서 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.
css 변수를 적극 활용하셔서 놀랐습니다! 저도 최근 프로젝트에서 tailwindCSS와 함께 css 변수를 사용해 편리하게 작업을 하고 있거든요. 그런데 기본 css 옵션이 아닌 값으로 설정하는 거의 모든 경우에 대해 css 변수를 사용하신 것으로도 보이네요. 저는 값을 입력할 때에 css 변수를 사용하기보다는 유지보수의 변리성을 위해 css 변수를 사용하는데요, 동욱님은 어떤 목적으로 css 변수를 사용하시는지 궁금합니다!
추가로 css 변수 네이밍의 일관성을 가져가는 것도 고려해 보시면 좋을 것 같습니다. 프로젝트 규모가 커지면 자연스럽게 컬러시스템의 필요성에 대해 느끼게 되는데, 저는 당시에 여러 기업의 컬러시스템 자료를 보며 [category]-[option(scale)] 형식으로 정립했습니다! 구체적인 예시가 있으면 좋을 듯해 코드에 추가 코멘트 남겨두겠습니다!
https://gds.gmarket.co.kr/foundation/color
https://developers.naver.com/console/clova/client/Design/DesignFoundation/Color.md#DesignColorPalette
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.
이번에는 연습해본다는 느낌으로 가능한 부분에 대해서 다 css 변수를 적용하고자 하였습니다. 실제 프로젝트를 진행할 때는 말씀주신 것처럼 하는 게 당연히 좋을 것 같습니다.
링크 감사합니다 ! 안 그래도 코딩하는 과정에서 변수 이름 짓는 게 어려웠었는데 ㅜㅜ 보내주신 링크 참고해서 다음 번에는 더 좋은 프로젝트 진행할 수 있도록 하겠습니다!
--primary-bg: #0a192f; | ||
--secondary-bg: #172a45; | ||
--item-bg: #112240; | ||
--text-primary: #ccd6f6; | ||
--text-secondary: #8892b0; | ||
--accent-color: #1a1a1a; | ||
--button-color: #fafaf8; | ||
--border-color: #233554; |
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.
현재 정의된 css 변수들을 보면 어느 용도로 사용될지가 명확하게 보이는 대신 재사용될 가능성은 낮아 보입니다. css변수를 유지보수의 편리성을 위해 사용한다는 관점에서 봤을 때, 한 번만 사용되는 값에 대한 css변수의 사용은 불필요한 추상화로 오히려 가독성만 낮추는 일이 될 수 있다고 생각해요.
추가로 button-color라는 css변수가 button의 background color로 사용되고 있는데, bg가 아닌 color로 표현되고 있는 점 등이 명확한 네이밍의 장점 또한 해칠 수 있을 것 같습니다.
예를 들어서 저는 구체적으로 어떤 태그에서 쓰이는지를 명시하기보다는 color 전반을 하나의 카테고리로 잡고 [category]-[option(scale)] 방식으로 네이밍 합니다! 이런 방식도 있구나 참고해 보시면 좋을 것 같아요!
/* variables.css */
--color-primary-900: #0a192f;
--color-primary-800: #112240;
/* ... */
--color-primary-200: #ccd6f6;
--color-primary-100: #fafaf8;
/* style.css */
button {
background-color: var(--color-primary-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.
감사합니다!!
--input-min-width: 200px; | ||
--input-width-ratio: 70%; | ||
--checkbox-size: 20px; | ||
--button-size: 32px; |
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.
위에 남긴 코멘트에 이어서 말씀드리자면, 이렇게 특정 태그나 요소에 사용되는 값들은 저는 style.css에 값 자체로 직접 입력하는 것을 선호합니다. 이렇게 하면 해당 클래스나 태그에 대한 스타일을 style.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.
저도 애플리케이션에서 글로벌하게 사용되는 min-width
나 GNB의 높이와 같은 고정값들은 CSS 변수로 분리하고, 컴포넌트 구현 시에 사용되는 값들은 직접 기입하는 방식이 좋다고 생각합니다.
이번 과제의 특성을 고려했을 때, 체크박스와 버튼이 여러 용도로 사용되지 않았기 때문에 변수 처리를 하는 것도 좋은 방법이라고 생각합니다 :)
const checkbox = document.createElement('input'); | ||
checkbox.type = 'checkbox'; | ||
checkbox.checked = todo.checked; | ||
checkbox.addEventListener('change', () => { | ||
toggleTodo(date, index); | ||
renderTodoList(date); | ||
}); | ||
|
||
const textSpan = document.createElement('span'); | ||
textSpan.textContent = todo.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.
input과 span을 label로 묶거나, span 대신 label을 사용해서 text를 클릭해도 check가 되도록 하면 더 좋은 사용자 경험을 제공할 수 있을 것 같습니다! input과 label을 같이 사용하면 좋을 때가 많아서 mbn 링크를 첨부해 드립니다. 한번 읽어 보시면 좋을 것 같아요.
https://developer.mozilla.org/ko/docs/Web/HTML/Element/label
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.
좋은 말씀 감사합니다! 제가 코드 짤 당시 객체 구성에 대해 명확히 정리하지 않고 그냥 시작했어서 UX적인 부분을 충분히 고려하지 못했던 것 같습니다 ㅜㅜ
form.addEventListener('submit', (event) => { | ||
event.preventDefault(); | ||
|
||
const text = input.value.trim(); | ||
if (!text) { | ||
return; | ||
} | ||
|
||
addTodo(today, text); | ||
input.value = ''; | ||
renderTodoList(today); | ||
}); |
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.
리액트에서는 renderTodoList
를 호출해도 가상 돔과 비교하여 실제 추가된 투두 하나만 렌더링하겠지만, 그에 반해 바닐라js에서는 전체 돔을 다시 그려야 하기 때문에 특히 투두 요소가 많아질수록 상대적으로 성능이 안 좋아질 수 있을 것 같습니다. renderTodoList
대신에 새 투두만 돔에 추가하는 addNewTodo
같은 로직이 따로 있었다면 성능 측면에서도 좋았겠지만, 코드는 너무 깔끔하네요!
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 deleteBtn = document.createElement('button'); | ||
deleteBtn.textContent = CONSTANTS.DELETE; | ||
deleteBtn.addEventListener('click', () => { | ||
removeTodo(date, index); | ||
renderTodoList(date); | ||
}); |
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.
app.js에서의 추가 버튼 이벤트 핸들러와 마찬가지입니다! 삭제하는 요소를 추적해 돔에서 그 요소만 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.
전반적으로 관심사의 분리가 잘 되어 있는 코드라고 느꼈습니다. 특히 todo 로직과 dom에 렌더링하는 로직을 별도의 파일로 분리한 게 너무 좋았습니다. 가독성 높은 코드를 지향하는 입장에서 코드의 짜임 측면으로는 그저 배울 게 너무 많았고, css 변수 관련해서 의견을 나누면 좋을 것 같아 관련 코멘트 남겼습니다! 고생하셨습니다!
헉. vscode에서 pr 관련 익스텐션을 처음 사용해 봤는데 개별 코멘트를 달고 있었군요?! . . . 많은 알림이 가게 해서 죄송합니다.. . .
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.
안녕하세요 동욱 님!
프론트엔드 운영진 송유선입니다. 우선 1주차 과제하시느라 고생 많으셨습니다 🎉
시맨틱 구조를 적절하게 활용하시고 모듈화에 신경 쓰시면서 CSS 변수를 활용해서 디자인 시스템을 구축하시는 등, 전반적으로 코드를 짜실 때 세심하게 신경 쓰신 게 느껴지는 과제였어요👍🏻 추가적으로 추가되었으면 좋겠다- 싶은 부분들을 리뷰로 달아보았으니 한 번 참고해주시면 좋을 것 같습니다! 그리고 현재 과제에서는 필수 요건인 투두 개수가 구현되지 않았는데, 오늘 스터디에서 리팩토링하실 때 해당 부분도 추가해보시는 걸 추천드려요! 이미 코드가 괜찮게 짜여 있어서, 업데이트 함수 부분만 새로 넣으면 될 듯 합니다. 전체 투두 개수는 todos.length
같은 코드로 구하실 수 있을 거고, 완료된 투두 개수는 todos.filter(todo => todo.checked).length
같은 코드로 구하실 수 있을 것으로 보여요.
다음 2주차 과제도 파이팅입니다! 🔥
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.
constant.js와 todo.js를 보면서 이번 과제 하실 때 코드를 구조적으로 짜려고 많이 노력하셨다는 걸 느낄 수 있었습니다! 모듈화가 잘 되어 있어서 유지보수에도 유리할 것 같다는 생각이 드네요.
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.
js로 돔을 구성할 때 선언적인 방식을 사용하면서 적절한 시맨틱 태그 요소를 활용한 점이 좋아요. header, h1, p등으로 문서 구조를 정확히 표현하신 것 같네요.
export function saveTodos(date, todos) { | ||
const allTodos = loadAll(); | ||
allTodos[date] = todos; | ||
saveAll(allTodos); | ||
} |
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.
로컬 스토리지 저장 로직에서 try-catch 문을 활용해서 에러관런 처리를 해주면 조금 더 섬세한 코드가 되지 않을까 싶어요. 물론 간단한 규모의 플젝이기 때문에 예외 처리가 필수적이지는 않지만, 로컬 스토리지 저장이 늘 아무 문제 없이 성공하는 것은 아니니까요! 대표적으로 용량 제한을 넘어가면 QuotaExceededError라는 Dom error를 발생시키거든요. 아래 링크에서 확인할 수 있는 예외들도 있으니, 다음에는 이런 부분들에 대해서 간단하게라도 에러 처리를 넣어주시면 더욱 완성도 높은 코드가 되지 않을까 싶습니다.
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.
감사합니다! local storage 에러 관련 부분은 제가 충분히 찾아보지 않은 채 진행하여 발생한 것 같습니다 해당 부분 참고하여 성능 개선 해보겠습니다!
const today = new Date().toLocaleDateString('ko-KR', { | ||
year: 'numeric', | ||
month: 'long', | ||
day: 'numeric', | ||
weekday: 'long', | ||
}); |
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 today = new Date().toLocaleDateString('ko-KR', { | |
year: 'numeric', | |
month: 'long', | |
day: 'numeric', | |
weekday: 'long', | |
}); | |
export function getFormattedDate() { | |
return new Date().toLocaleDateString('ko-KR', { | |
year: 'numeric', | |
month: 'long', | |
day: 'numeric', | |
weekday: 'long', | |
}); | |
} |
이런 식으로 약간 바꾼 다음에 modules 폴더에 파일로 분리해서 넣고, app.js에서 임포트해서 const today = getFormattedDate();
이런 식으로 사용해도 좋을 것 같아요.
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.
넵 감사합니다! 저 부분도 코드 작성하는 과정에서 대충 그냥 넘어갔던 것 같아서 더 수정하도록 하겠습니다
export function renderTodoList(date) { | ||
const todoListContainer = document.getElementById('todo-list'); | ||
todoListContainer.innerHTML = ''; | ||
|
||
const todos = loadTodos(date); | ||
todos.forEach((todo, index) => { | ||
const li = document.createElement('li'); | ||
li.className = 'todo'; | ||
|
||
const checkbox = document.createElement('input'); | ||
checkbox.type = 'checkbox'; | ||
checkbox.checked = todo.checked; | ||
checkbox.addEventListener('change', () => { | ||
toggleTodo(date, index); | ||
renderTodoList(date); | ||
}); | ||
|
||
const textSpan = document.createElement('span'); | ||
textSpan.textContent = todo.text; | ||
|
||
const deleteBtn = document.createElement('button'); | ||
deleteBtn.textContent = CONSTANTS.DELETE; | ||
deleteBtn.addEventListener('click', () => { | ||
removeTodo(date, index); | ||
renderTodoList(date); | ||
}); |
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.
현재 todo 항목마다 개별 이벤트 리스너를 생성하고 있어서 메모리 사용량이 증가할 수 있어요. 또, todo 상태가 변경될 때마다 전체 목록을 리렌더링하고 있기 때문에 성능도 저하될 수 있습니다. 이벤트 위임을 활용하시거나 전체 목록 대신 개별 항목만 업데이트 시키는 등의 방향으로 수정하신다면 더욱 최적화된 코드가 되지 않을까 싶습니다.
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 text = input.value.trim(); | ||
if (!text) { | ||
return; | ||
} |
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문을 하나 넣어주는 것도 좋을 것 같아요. 아래와 같이 수정해보는 건 어떤가요?
const text = input.value.trim(); | |
if (!text) { | |
return; | |
} | |
const text = input.value.trim(); | |
if (!text) { | |
alert('할 일을 입력해 주세요!'); | |
return; | |
} |
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.
네 UX적인 부분에 대한 고려가 좀 부족했던 것 같네요 ㅜㅜ 추후 반영해서 수정하도록 하겠습니다!
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.
1주차 과제여서 해당 아이콘으로 했습니다,, 혹시 너무 관련 없다 싶으면 수정하도록 하겠습니다!
.todo:hover { | ||
transform: var(--transform); | ||
} |
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.
현재 투두리스트 각 항목에 커서를 가져가서 호버 상태가 되면 항목이 오른쪽으로 약간 슬라이딩 되는 애니메이션 효과를 넣어주셨는데, 사용자 경험을 고려하면 살짝 비효율적인 애니메이션이라는 생각이 듭니다. 사용자가 해당 투두를 완료해서 체크박스를 클릭하려고 하거나 삭제하려고 할 때, 체크박스/삭제 버튼을 클릭하고자 해당 위치로 커서를 가져갔는데 금세 옆으로 이동해버리니까요. 사용자 입장에서는 보이는 위치에 커서를 가져가도 목적하던 버튼이 다른 곳으로 가버리는 꼴이니 약간 의아하게 느껴질 수 있는 포인트라고 보여요. 해당 애니메이션이 사용자가 선택하고자 하는 투두 항목을 직관적으로 보여주려는 의도라면, 차라리 호버 시 해당 투두의 배경색을 살짝 바꾸거나 아니면 scale을 살짝 키워서 해당 투두가 약간 확대되는 정도로만 변화를 줘도 좋을 것 같습니다.
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.
다른 분들의 리뷰들도 읽어보면서 저도 모르는 부분을 많이 배울 수 있었고, 모듈화가 굉장히 인상적인 코드라고 생각이 드네요!
고생하셨습니다 :)
--input-min-width: 200px; | ||
--input-width-ratio: 70%; | ||
--checkbox-size: 20px; | ||
--button-size: 32px; |
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.
저도 애플리케이션에서 글로벌하게 사용되는 min-width
나 GNB의 높이와 같은 고정값들은 CSS 변수로 분리하고, 컴포넌트 구현 시에 사용되는 값들은 직접 기입하는 방식이 좋다고 생각합니다.
이번 과제의 특성을 고려했을 때, 체크박스와 버튼이 여러 용도로 사용되지 않았기 때문에 변수 처리를 하는 것도 좋은 방법이라고 생각합니다 :)
flex-shrink: 0; | ||
font-size: var(--font-size-xxl); | ||
width: var(--button-size); | ||
height: var(--button-size); |
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.
OS 내장 이모지는 텍스트라서 별도의 width
, height
설정이 없는게 더 깔끔할 것 같아요!
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.
저도 VanillaJS가 처음이라서 어떻게 초기 렌더링을 할 지에 대해서 고민했는데, Top-level 컨테이너만 렌더링한 후에 함수로 초기 렌더링을 하는 방식이 굉장히 깔끔한 것 같아요!
|
||
export function removeTodo(date, index) { | ||
const todos = loadTodos(date); | ||
todos.splice(index, 1); |
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
메소드를 사용했었는데, 이러한 간단한 프로젝트나 원본 배열을 직접 조작해도 문제가 없는 경우에는 splice
메소드를 사용해도 좋은 것 같네요!
Postscript
- HTML 구조랑 JS 파일은 상대적으로 쉽게 작성했었고, 생각 외로 CSS 작성이 오래 걸렸습니다.
- 기본적으로 연구실 서버에서 vscode로 작업을 하다 보니, 초기 세팅에 난항을 겪었습니다. 더해, 처음 프로젝트 개요를 구성할 때 가능하면 파일을 기능별로 나누어 구성하고자 하였습니다. 이 과정에서 vite 번들러를 사용하였습니다. 자세한 폴더 및 파일 구조는 README에 기입하였습니다.
- 굉장히 오랜만에 프론트엔드 기술 스택을 사용해본 것 같은데, 공부하고 코드 작성하는 과정에서 재미를 느꼈습니다. 좋은 경험이 되었다고 생각합니다.
- 배포 링크는 다음과 같습니다.
Key Questions
1. DOM은 무엇인가요?
DOM(Document Object Model), 문서 객체 모델은 XML, HTML 문서의 각 항목을 계층적 트리 구조로 표현한 프로그래밍 인터페이스로, JavaScript를 사용하여 해당 문서를 조작(요소 및 이벤트 추가/삭제/수정)할 수 있도록 합니다. 현재 W3C(World Wide Web Consortium) 표준으로 사용되고 있으며, 각종 표준화 API의 기본이 됩니다.참고 1
2. 이벤트 흐름 제어(버블링 & 캡처링)이 무엇인가요?
표준 DOM 이벤트에서 정의한 흐름은 크게 세 단계, 캡처링, 타깃, 그리고 버블링 순으로 이루어집니다. 그 중에서도 캡처링은 이벤트가 루트 노드부터 시작하여 부모->자식으로 전달, 버블링은 반대로 리프 노드부터 시작하여 자식->부모 순으로 전달되는 단계를 뜻합니다. 기본적으로 이벤트 버블링이 동작하며, 특수하게 addEventListener method 파라미터 중 useCapture를 true로 설정할 경우 캡처링이 동작(default value: false)합니다.참고 1
참고 2
3. 클로저와 스코프가 무엇인가요?
스코프(Scope)는 변수에 접근할 수 있는 범위를 의미하며, 어떤 변수가 어디에서 유효한지 결정하는 개념입니다. JavaScript에서 스코프는 전역 스코프, 지역 스코프(module/function)로 나누어지며, ES6 이후 block 스코프가 추가되어 더욱 엄격한 유효성 지정이 가능하게 되었습니다.클로저(Closure)는 함수와 그 함수가 선언된 외부 환경(lexcial scope)와의 조합입니다. 즉, 내부 함수가 외부 함수의 변수에 접근할 수 있도록 만드는 기술입니다. 클로저를 사용하여 코드를 구성하게 되면 데이터 보호, 상태 유지, 메모리 관리 등 여러 방면에서 이점을 가질 수 있습니다.
참고 1
참고 2
참고 3