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 13 commits into
base: master
Choose a base branch
from

Conversation

youdame
Copy link

@youdame youdame commented Mar 15, 2024

느낀점

바닐라 js을 너무 오랜만에 사용해서..ㅎㅎ 쉽지 않았습니다.
드래그앤드랍 기능을 적용해보려고 했는데 ㅋㅋㅋㅋㅋ 아직 미완성이네요.
스크롤바 css가 왜 적용되지 않는지 모르겠습니다! ! !

배포링크

https://vanilla-todo-19th-navy.vercel.app/

기능

  • 초기 진입 시 이름 입력해서 ~의 Todo-List라고 보여주기
  • 할 일 추가, 삭제
  • 동그라미 버튼 클릭 시 done으로 이동
  • 체크 버튼 클릭 시 todo로 이동
  • 날짜 보여주기
  • todo, done 할 일 개수 보여주기
  • 로컬스토리지 저장

reset.css, global.css, og 태그도 적용해봤습니다.

key Question

  • DOM은 무엇인가요?
    DOM (Document Object Model)은 문서 객체 모델이다. 웹 페이지에 나타나는 HTML 문서 전체를 객체로 표현한 것이라고 생각하면 된다. DOM을 활용해서 웹 페이지 내부의 노드를 수정할 수도 있고, 추가할 수도 있다. DOM은 html 문서를 객체화한 것이기 document 객체를 최상위로 해서 계층 구조를 이루고 이를 나무에 비유해서 DOM 트리라고 한다. DOM 트리에서는 각 객체를 노드라고 표현한다. 각 노드에는 부모, 자식, 형제 노드 관계가 존재한다. 태그(html, head, body, h1, h2, script)를 표현하는 노드는 '요소 노드'라고 하고, 문자를 표현하는 노드는 '텍스트 노드'라고 한다.

  • HTML (tag) Element를 JavaScript로 생성하는 방법은 어떤 것이 있고, 어떤 방법이 가장 적합할까요?
    (1) insertAdjacentHTML
    element.insertAdjacentHTML(position, text);
    특정 위치에 원하는 node를 추가 할 수 있는 메서드
    장점 - 가독성이 좋다.
    단점 - 보안 이슈가 있다. 해커가 웹 페이지에 악성 스크립트를 삽입하는 XSS(Cross-Site Scripting) 공격에 취약하다.
    (2) createElement
    document.createElement(tagName);
    특정한 태그를 가지는 element를 생성할 수 있는 메서드
    장점: HTML Element를 생성해 append하기 때문에 node만 삽입이 가능하다.
    단점: 가독성이 안 좋다. 또 HTML element를 생성할때마다 dom tree 자료구조를 탐색해야하기 때문에 js의 성능을 저하시킨다.

  • Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?

태그 이름 용도
header 영역 위쪽에서 로고나 제목, 메뉴 같은 걸 담고 있는 도입부
main 사이트의 본격적인 내용으로 페이지에서 딱 한 번만 사용 가능
footer 영역 아래쪽에서 여러 가지 연락처나 관련 정보를 담고 있음
article 하나의 완성된, 독립적인 내용을 나타내는 영역
section 어떤 것의 일부분을 나타내는 영역
figure 이미지와, 이미지 설명을 담고 있는 영역

image

Semantic tag란 HTML에서 의미론적인 요소를 가리킨다. 즉, div와 기능은 똑같지만, 의미가 담겨있는 태그들을 '시맨틱 태그'라고 한다. 엄격한 사용법이 있는 건 아니다. 시맨틱 태그를 잘 활용하면 검색 엔진 최적화(SEO)나 접근성(Accessibility)을 높이는데 도움이 된다. 이러한 요소들은 그들이 담고 있는 콘텐츠의 의미를 명확하게 설명한다.

  • Flexbox Layout은 무엇이며, 어떻게 사용하나요?
    Flexbox Layout은 CSS의 레이아웃 모델 중 하나로, 이를 활용하면 요소들을 부모 요소 내에서 유연하게 정렬, 배치할 수 있다.

=> Flexbox에서는

  1. 배치 방향은 flex-direction
  2. 정렬은 justify-content, align-items
  3. 요소가 넘칠 때는 flex-wrap
  4. 요소 간격은 gap
  5. 크기 늘이거나 줄이기는 flex-grow, flex-shrink, flex-basis
    를 사용하여 요소를 배치한다.
  • JavaScript가 다른 언어들에 비해 주목할 만한 점에는 어떤 것들이 있나요?
    자바스크립트는 인터프리터 언어이기 때문에, 자바와 같이 컴파일이 필요한 다른 프로그래밍 언어에 비해 시간이 적게 소요된다. 동적이고 유연한 언어로, 클라이언트 측 웹 개발에 널리 사용된다. 동적인 웹 페이지를 만들 수 있고, 이벤트 처리와 상호작용이 용이하며, 다양한 라이브러리와 프레임워크를 지원한다.

  • 코드에서 주석을 다는 바람직한 방법은 무엇일까요?
    주석이 코드를 더 어렵게 만들지 않도록 최대한 간결하고 명확하게 작성하는 게 중요하다고 생각한다.

Copy link

@Dahn12 Dahn12 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 +55 to +60
const inputValue = $('.input').value.trim();
if (!inputValue) {
$('.error').textContent = '내용을 입력해주세요';
return;
}
$('.error').textContent = '';
Copy link

Choose a reason for hiding this comment

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

이부분은

Suggested change
const inputValue = $('.input').value.trim();
if (!inputValue) {
$('.error').textContent = '내용을 입력해주세요';
return;
}
$('.error').textContent = '';
const inputValue = document.querySelector('.input');
if (!inputValue.value.trim()) {
alert = ('내용을 입력해주세요');
}

로 하면 더 깔끔할거 같아요!

Copy link

Choose a reason for hiding this comment

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

앗 다시 확인해보니 error을 쓰신 이유가 있었네요! alert 부분은 무시해 주셔도 됩니다! 개인적으로는 inputValue와 같은 변수에는 하나의 클래스만 선택하도록 하는 것이 또 쓰일 경우를 대비해서 더 좋더라구요. if문안에도 직관적인 내용이 들어왔을 때가 유지 보수하기 좋았던 것 같은데 이부분은 개인 취향이 아닐까.. 생각합니다!

$('.error').textContent = '';

// 새로운 list 아이템 만들기
const newItem = createItem(inputValue);
Copy link

Choose a reason for hiding this comment

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

이부분은 입력 버튼을 눌렀을 때로 이벤트를 주면 좀 더 직관적인 코드가 되었을거 같아요!

Copy link
Author

Choose a reason for hiding this comment

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

form 태그에 이벤트를 걸어둔 거라 입력 버튼을 누르거나 엔터를 눌렀을 때 addItem 함수 내부의 createItem이 실행돼요!

Copy link

Choose a reason for hiding this comment

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

아하! 제 코드에도 달아주신 리뷰도 확인했습니다! 많이 배워가요!

Comment on lines +86 to +88
circleIcon.classList.toggle('fa-circle');
circleIcon.classList.toggle('fa-check-circle');
$(targetList).append(clickedItem);
Copy link

Choose a reason for hiding this comment

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

저두 todo와 done에 따라 다른 아이콘을 주고 싶어서 css로만 조작을 했었는데, 이렇게 따로 append를 해주니 더 좋은거 같아요! 배워갑니다~

Comment on lines +130 to +131
// 사용자 이름 설정
const showUserName = () => {
Copy link

Choose a reason for hiding this comment

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

사용자 이름 설정까지!

Copy link
Collaborator

Choose a reason for hiding this comment

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

저도 결과 화면 이용해보면서 이거 보고 재치있고 귀엽다고 생각했어요ㅎㅎ 디테일 굿입니당👍👍

}
};

const addDragDropEvents = () => {
Copy link

Choose a reason for hiding this comment

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

이부분은 스크롤이 안되는 부분 때문에 추가하신 걸까요? 저도 스크롤이 안되는 문제가있어서 고민 중인데 css 문제인지 잘 모르겠어서🥲 혹시 좋은 방안이 있다면 같이 이야기 해봐요!

Copy link
Author

Choose a reason for hiding this comment

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

앗 아니요 ! 드래그앤드랍 기능을 만드려고 추가한 코드였어요 ㅋㅋ 드래그앤드랍이 되긴 하는데, 반쪽짜리 코드입니다 ㅠ 스크롤은 그냥 css에서 처리해주면 됩니다!

html,
body {
height: 100%;
-ms-overflow-style: none; /* IE and 엣지 */
Copy link

Choose a reason for hiding this comment

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

브라우저 마다 다르게 설정하신 것도 배워갑니다!

Comment on lines +57 to +68
/*
7. Avoid text overflows
*/
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}
Copy link

Choose a reason for hiding this comment

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

한번에 처리하니까 더 이해하기 좋은거 같아요!

Copy link
Author

@youdame youdame Mar 16, 2024

Choose a reason for hiding this comment

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

@Dahn12 보통 reset.css은 브라우저의 stylesheet( 브라우저마다 기본으로 제공하는 스타일)의 영향력을 없애기 위해, global.css는 공통적으로 적용할 스타일링을 위해 많이 사용하는 거라 서치해보셔도 좋을 거 같아요!!

Comment on lines +88 to +93
.list {
display: flex;
flex-direction: column;
gap: 1rem;
overflow: auto;
}
Copy link

Choose a reason for hiding this comment

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

앗 그리고 input 이 늘어나서 줄길이가 늘어날 경우에는 trash 버튼이 요소 가운데로 정렬될 수 있도록 css를 추가해주시면 더 깔끔해 보일거 같더라구요! 개인 취향입니당😅
스크린샷 2024-03-17 오전 12 44 38

Copy link
Collaborator

@mod-siw mod-siw left a comment

Choose a reason for hiding this comment

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

안녕하세요~ 19기 프론트 운영진 변지혜입니다🤗
reset.css와 global.css, 그리고 common.css를 따로 지정해주셔서 보다 효율적인 스타일 설정이 가능했던 코드 잘 봤습니다.
util도 따로 지정해주시고 JS 도 다양하게 활용해주셔서 많이 배워갑니다ㅎㅎ
첫주차 과제 정말 수고 많으셨어요! 스터디 시간에 뵙겠습니다~

Comment on lines +7 to +12
<link rel="stylesheet" href="./style/style.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" />
<meta property="og:title" content="TODO-LIST" />
<meta property="og:url" content="https://vanilla-todo-19th-navy.vercel.app/" />
<meta property="og:type" content="website" />
<meta property="og:description" content="오늘의 일정을 관리해보세요." />
Copy link
Collaborator

Choose a reason for hiding this comment

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

og 태그 작성해주신 점 좋네요! 미리보기까지 챙겨주신 섬세함이 돋보이는 것 같습니다ㅎㅎ

Comment on lines +3 to +14
// 오늘 날짜 문자열 반환
const getTodayDate = () => {
const today = new Date();
const year = today.getFullYear();
const month = (today.getMonth() + 1).toString().padStart(2, '0');
const date = today.getDate().toString().padStart(2, '0');

const dayToString = ['일', '월', '화', '수', '목', '금', '토'];
const day = dayToString[today.getDay()];

return `${year}년 ${month}월 ${date}일 ${day}요일`;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

이렇게 작성해주셨을 때 확실히 세세한 설정을 할 수 있어서 좋지만, 디테일한 부분이 필요하지 않을 때는 JS의 toLocaleDateString 를 써봐도 좋을 것 같아요. 설정을 한국어로 바꿔준 뒤 세부 설정을 long으로 해주면 읽기 편한 방식으로 바꿔주는 편리한 기능이라 참고링크 놓고 갑니다!

Comment on lines +100 to +101
updateListCount();
saveToLocalStorage();
Copy link
Collaborator

Choose a reason for hiding this comment

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

list count를 업데이트할 때마다 로컬 스토리지에 저장하다보니, updateListCount 함수에 saveToLocalStorage 함수를 넣으면 타 함수 작성시에 둘 중 한 가지 기능을 빼먹을 가능성이 줄어들 것 같아요!

Comment on lines +130 to +131
// 사용자 이름 설정
const showUserName = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

저도 결과 화면 이용해보면서 이거 보고 재치있고 귀엽다고 생각했어요ㅎㅎ 디테일 굿입니당👍👍

Comment on lines +132 to +142
const savedUserName = localStorage.getItem('userName');
if (savedUserName) {
$('.userName').textContent = `${savedUserName}의 `;
return;
}
const userName = prompt('이름을 알려주세요!');
if (userName) {
$('.userName').textContent = `${userName}의 `;
localStorage.setItem('userName', userName);
}
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

로컬 스토리지에 userName이 있으면 해당 텍스트를 띄우고, 없으면 이름을 받아 그걸 저장한 뒤 띄우는 기능을 하는 함수로 보여요! 디테일이 정말 굿입니다...👍 여기서 else if 문을 따로 쓰지 않으시고 if문을 따로 2개 쓰신 이유가 있는지 궁금해요! 제가 인지하지 못한 다른 이유가 없었다면 else if로 되어있으면 조금 더 가독성이 좋아지지 않을까 조심스럽게 의견 내봅니다 ㅎㅎ

Copy link
Author

Choose a reason for hiding this comment

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

else if를 사용하는 것보다 early return을 해주는 걸 선호하는 편입니다! 코드 깊이가 얕아지는 장점이 있어서요 ㅎㅎ

무조건 early return을 하는 게 적절하다고 할 수는 없지만, 저는 유효하지 않은 경우를 앞 부분에서 처리해주는 게 더 가독성 있게 여겨지는 거 같아요~~
early return

Comment on lines +1 to +9
function $(selector) {
return document.querySelector(selector);
}

function $all(selector) {
return document.querySelectorAll(selector);
}

export { $, $all };
Copy link
Collaborator

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.

'document.querySelectorAll(selector)'를 바로 리턴해서
const draggableItems = $all('.draggable');
const containers = $all('.list');
이런식으로 html 요소를 받아서 활용할 수 있게 하셔서 되게 좋은 아이디어 인 것 같다는 생각이 듭니다!

함수 이름에 $를 붙인 이유가 궁금한데 오늘 이따 만나면 여쭤볼게용!!!

Comment on lines +95 to +96
// 스크롤바 css가 안 먹는 이유를 모르겠음..
/* 스크롤바 막대 */
Copy link
Collaborator

Choose a reason for hiding this comment

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

스크롤바 커스텀 코드 잘 써주신 것 같은데! 왜 안되었을까요?😥 한 가지 제안점으로는 ul보다 한 단계 상위 태그에 설정을 먹여보면 어떨까 싶은 생각이 듭니다!!

@jinnyleeis
Copy link

jinnyleeis commented Mar 17, 2024

안녕하세요 유담님! 사용자 이름 입력 받기 기능도 추가적으로 구현하시고,
이벤트 핸들링 시 addEventListner를 잘 활용하신 것 같네요!!
그리고 UI가 너무 뽀짝하고 귀여운 것 같습니다! ㅎㅎㅎ
그리고 저는 css 코드를 한 파일 안에서 다 작성해서 가독성이 안좋았는데, 모듈별로 나누어서 관리하셔서 인상깊었습니다!
반응형이 아닌 것 같은데, 모바일로 접속하거나 브라우저의 뷰포트가 변화해도, 반응형으로 작동하도록 css 코드를 수정하면 더 좋을 것 같아요!

Comment on lines +1 to +9
function $(selector) {
return document.querySelector(selector);
}

function $all(selector) {
return document.querySelectorAll(selector);
}

export { $, $all };

Choose a reason for hiding this comment

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

'document.querySelectorAll(selector)'를 바로 리턴해서
const draggableItems = $all('.draggable');
const containers = $all('.list');
이런식으로 html 요소를 받아서 활용할 수 있게 하셔서 되게 좋은 아이디어 인 것 같다는 생각이 듭니다!

함수 이름에 $를 붙인 이유가 궁금한데 오늘 이따 만나면 여쭤볼게용!!!

js/script.js Outdated

// 쓰레기통 아이콘
const trashIcon = document.createElement('i');
trashIcon.classList.add('fa-solid', 'fa-trash-can', 'cursor-pointer');

Choose a reason for hiding this comment

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

클래스 속성을 요소에 적용할 때 classList.add를 사용해서 한 번에 여러가지 스타일 속성을 적용하신게 정말 효율적인 것 같아요!!
앞으로 저도 classList.add 많이 활용해야겠네요!

js/index.js Outdated
$('.input').value = '';

newTodoItem.querySelector('.fa-circle').addEventListener('click', moveTodo);

Choose a reason for hiding this comment

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

저는 인라인 이벤트 핸들링 방식을 사용했는데
이벤트 핸들링할 때 addEventListener()를 잘 활용하신 것 같아 인상깊습니다!
실제로 이벤트 핸들링 할 때 addEventListener()를 쓰는게

  1. 등록한 이벤트 핸들러를 removeEventListener()로 제거할 수도
  2. 이벤트 캡처링(capturing)과 버블링(bubbling) 단계를 제어할 수도
  3. 동시에 특정 요소의 이벤트에 여러 핸들러를 등록할 수 있다는 점 등등으로 인해 더 좋다고 하더라고요!!
    addEventListener()를 활용하는 걸로 저도 코드를 리팩토링해야겠단 생각이 드네요!

@@ -137,6 +141,47 @@ const showUserName = () => {
}
};

const addDragDropEvents = () => {
const draggableItems = $all('.draggable');

Choose a reason for hiding this comment

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

드래그가 인식은 되는데,
드래그해서 할일을 이동시키는 기능은 아직 구현이 안되신 것 같은데,
저도 드래그 기능을 구현하고 싶었으나 시간 관계로 구현하지 못했는데
이에 대해 이따가 같이 이야기해보면 좋을 것 같아요!

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