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주차] 고주희 미션 제출합니다. #1

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

ZUITOPIA
Copy link

@ZUITOPIA ZUITOPIA commented Aug 26, 2024

안녕하세요, LG U+ URECA 프론트엔드 대면반 1기 고주희입니다.

노마드코더 JS 강의 수강, Core Javascript 책 스터디, 유레카 수업에서 다룬 JS, 며칠 전 완강한 드림코딩의 JS 기초 강의 수강 경험 등을 바탕으로 어쩌면 금방 할 수 있지 않을까 싶었으나 .. 역시나 DOM으로 태그 하나하나에 접근하고 업데이트해줘야하는 작업이 무척 번거롭고 어렵다는 생각이 들었습니다. 항상 react에 의존해서 구현해왔었다는 것을 다시 한 번 깨닫는 시간이었습니다. 🥲

알고 있다고 생각했는데 생각보다 훨씬 더 빈틈이 많았고, 꾸준히 반복적으로 JS를 공부해야겠다고 다짐했습니다. (믿어주십쇼)

알게 된 부분

  • querySelector과 getElementsByClassName의 차이를 알 수 있었습니다.
  • input 값에 접근하고 localStorage에 접근 (값 업데이트 후에도 localStorage에 업데이트) 하는 흐름을 익힐 수 있었습니다.

앞으로 개선하고자 하는 부분

  • 공부를 위한 스터디이므로 주석을 조금 더 명확하게 달기
  • 더 자잘한 기능 단위의 commit 하기
  • pr 요청 후 추가 기능 구현해보기
  • 배포 🔥
  • 코드리뷰 의견 반영하여 리팩토링
  • 스크롤바 스타일 구현 디테일 더 잡기

KEY QUESTION

  1. DOM이란 무엇인가요?
  • document object model
  • Javascript 엔진이 제공하는 WebAPI 중 DomAPI를 이용해 접근하여 HTML을 동적으로 변경할 수 있도록 하는 것,, 이라고 생각해보았으나 정확한 답변이 어렵습니다 🥹
  1. JavaScript로 DOM을 조작하는 방법은 어떤 것이 있나요?
  • innerHTML으로 태그 자체를 변경하거나, querySelector(혹은 getElementById)와 같은 메서드를 이용하여 태그에 접근할 수 있으며, 값에 태그를 createElement 하는 것도 가능한 것으로 알고 있습니다.
  1. Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?
  • 종류 : header, section, footer ..
  • 무엇을 하는 것인지 의미를 담은 태그, 코드를 봤을 때 웹 사이트 구조를 더 이해하기 쉽도록 하기 위함이라고 알고 있습니다.
  1. Flexbox Layout은 무엇이며, 어떻게 사용하나요?
  • display: flex를 이용하여 구현하는 layout 구조입니다. flex-direction으로 row,column 전환이 가능하며 justify-contents, align-items에 center를 지정하거나 space- 를 이용하여 일정한 간격을 두는 것으로 알고 있습니다.

배포

  • 스터디장 주현님께서 공유해주신 vercel 배포 방법을 보고 배포 완료하여 링크 공유합니다!
    https://zuitopia-todo.vercel.app/
  • 결과물은 아래 사진과 같습니다.
    image

Copy link
Member

@corinthionia corinthionia left a comment

Choose a reason for hiding this comment

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

안녕하세요 주희 님!
거의 모든 줄에 상세하게 주석을 달아 주셔서 어떠한 과정으로 코드를 작성하셨는지 그 흐름을 엿볼 수 있었던 것 같습니다 👍🏻 몇 가지 코멘트 남겨 두어서 확인해 보시면 좋을 것 같아요 🙂 과제 고생하셨습니다!!

script.js Outdated
function handleAddTodo() {
let inputValue = document.getElementById("todo-input").value; // 입력한 todo 집중
Copy link
Member

Choose a reason for hiding this comment

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

또한 document.getElementById("todo-input").value 가 자주 사용되므로, 최상단에 미리 변수에 할당하고 해당 변수를 사용하면 가독성이 더욱 좋아질 것 같아요 👀

Copy link
Author

Choose a reason for hiding this comment

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

최상단이라고 하면 전역 변수로 할당하는 것 맞을까요 ?!

Copy link
Member

Choose a reason for hiding this comment

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

넵 맞습니다!

script.js Outdated

let todos = JSON.parse(localStorage.getItem("todos")) || []; // localstorage에 저장해둔 todo를 가져와서 객체로 (아직 아무것도 없다면 빈 배열로 초기화)
todos.unshift(inputValue); // 입력된 todo를 추가
Copy link
Member

Choose a reason for hiding this comment

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

unshift()를 사용하신 이유가 최신순으로 정렬하기 위함일까요?!
다른 분들 코드에도 코멘트 달았던 내용이긴 한데 unshift()는 원본 배열을 직접 변경하기 때문에, JavaScript로 배열을 조작할 때에는 새로운 배열을 만들고, 그 배열을 할당하는 방식으로 진행하는 것이 좋습니다!


그 이유가 궁금하시다면,,,

JS의 immutability(불변성) 관련된 문제인데 이 글에 자세히 나와 있어서 참고하시면 좋을 것 같아요!

간단히 설명드리자면, 배열의 값을 직접 변경할 경우 디버깅이 어렵고 의도치 않은 결과를 불러올 수 있기 때문에 배열의 값을 직접 변경하는 방식이 아닌 새로운 배열을 만들어 할당하는 방식을 추천합니다. 따라서 값을 직접 변경하는 push() , unshift(), splice() 등의 메서드보다 새로운 배열을 반환하는 map(), filter() 혹은 spread 연산자를 사용하는 방식을 권장합니다 👀 또한 나중에 React를 사용하실 때에도 배열 불변성을 지켜 주셔야 상태 변화 감지와 성능 최적화 부분에서 용이하답니다!

Copy link
Author

Choose a reason for hiding this comment

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

맞습니다! 최신순을 위해 push에서 unshift로 수정했었습니다! 아직 성능 최적화를 위한 코드작성 방법은 잘 모르는 상황인데 자세한 조언 감사합니다 ㅎㅎ

script.js Outdated
todos.unshift(inputValue); // 입력된 todo를 추가

localStorage.setItem("todos", JSON.stringify(todos)); // update 된 객체를 localStorage 에도 update
Copy link
Member

Choose a reason for hiding this comment

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

👍🏻👍🏻

script.js Outdated
Comment on lines 15 to 19
if (event.isComposing && event.key === "Enter") {
handleAddTodo(); // Enter 키가 눌리면 todo 추가 함수 호출
}
});
Copy link
Member

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.

한글로 input 작성 후 엔터키로 todo를 추가하면 한글이 두 번씩 나오는 현상이 있어서 isComposing으로 해결해보려고 추가한 코드인데, 이렇게 하게 되면 영어로 입력 시에는 엔터키가 안 먹더라구요.. 조금 더 해결해 보도록 하겠습니다!

// 초기화하지 않고도 배열에 추가된 항목을 화면에 표시할 수 있지만 -> 중복 문제, 성능 문제 생길 수 있음

todos.forEach((todo, index) => {
Copy link
Member

Choose a reason for hiding this comment

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

forEach() 사용 좋습니다!! 👍🏻

script.js Outdated
todos.forEach((todo, index) => {
let li = document.createElement("li"); // todo 목록에 들어있는 각각의 값 마다 li 태그 붙이기
li.innerHTML = `<span onclick="handleAddDone(${index})">${todo}</span> <i class="delete-btn" onclick="handleDeleteTodoItem(${index})"></i>`; // handleAddDone 함수와 handleDeleteTodoItem의 인자로 index를 넘겨주는 기능을 한 번에 처리하기 위함
Copy link
Member

@corinthionia corinthionia Aug 28, 2024

Choose a reason for hiding this comment

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

innerHTML은 주희 님이 사용하신 것처럼 스크립트를 문자열로 삽입할 수 있기 때문에 보안상 취약한 방법이라 여겨지고 있습니다! 따라서 createElementappend/appendChild를 사용하여 <script> 요소를 생성하고 삽입하는 방법이 더 안전한 방법이라고 합니다 👀

Copy link
Author

Choose a reason for hiding this comment

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

코드 관리 면에서 중요한 부분들을 많이 알아가는 것 같습니다! 이 부분도 참고하여 리팩토링 후 추가 커밋 하도록 하겠습니다 ㅎㅎ

script.js Outdated
Comment on lines 38 to 40

todos.splice(index, 1); // todos 배열 내의 index에 해당하는 값을 1개 삭제할 것
Copy link
Member

Choose a reason for hiding this comment

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

위에 언급한 배열 불변성을 고려하여 splice() 대신 filter() 메서드를 사용해 보면 좋을 것 같습니다!

Comment on lines +85 to +92
// 초기 렌더링 설정을 위한 코드
// DOM이 완전히 로드된 후에 초기화되도록 설정!
// 로컬 저장소에서 가져온 데이터로 초기 상태 보여질 수 있도록 함
// 이 코드가 없다면 페이지 로드 시 초기 목록을 로드하는 데 실패할 수 있음
renderTodos();
renderDone();
});
Copy link
Member

Choose a reason for hiding this comment

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

아주 좋습니다 👍🏻🎉

Comment on lines +100 to +112
.scrollbar::-webkit-scrollbar {
width: 10px;
}

.scrollbar::-webkit-scrollbar-thumb {
background: rgba(220, 20, 60); /* 스크롤바 색상 */
border-radius: 10px; /* 스크롤바 둥근 테두리 */
}

.scrollbar::-webkit-scrollbar-track {
background: rgba(220, 20, 60, 0.1); /*스크롤바 뒷 배경 색상*/
}
Copy link
Member

Choose a reason for hiding this comment

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

스크롤바 디자인까지 신경쓰시다니 멋져요 👏🏻

Copy link

@jaee55555 jaee55555 left a comment

Choose a reason for hiding this comment

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

localStorage부터 스크롤바 디자인까지, 세세한 부분을 다 챙기신 것같아서 주희님의 세심함을 알 수 있었습니다. 특히나 자세한 주석으로 설명해주셔서 코드를 쉽게 이해할 수 있었습니다.
주희님의 코드를 보면서 저 또한 많이 공부할 수 있었네요🤩
한 주동안 고생하셨습니다!

index.html Outdated
Comment on lines 21 to 28
<!-- 할 일 추가될 곳 -->
</ul>
</section>
<hr />
<section class="done-list-box">
<h4 id="done-list-title">💿 DONE (0)</h4>
<ul class="done-list">
<!-- 완료된 일 추가될 곳 -->

Choose a reason for hiding this comment

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

HTML 안에서 목록들이 추가될 곳에 주석으로 정리 해주셔서
DOM 조작할 때 항목들이 어디에 들어갈지 바로 알아볼 수 있어서 너무 좋습니다!

style.css Outdated
Comment on lines 7 to 9
font-family: "Binggrae-Two";
}

Choose a reason for hiding this comment

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

*을 사용하여 폰트를 전체적으로 적용해주셨네요!
저는 *을 생각하지 못해서 모든 font-family에 폰트명을 작성했는데 주희님 코드 덕에 쉽고 간단한 방법 배워갑니다!

Copy link
Member

@ongheong ongheong left a comment

Choose a reason for hiding this comment

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

안녕하세요 주희님! 1주차 미션에서 주희님의 코드 리뷰를 하게 되어 기쁩니다!
자바스크립트의 코드 스타일을 잘 적용해주셔서 많이 배워갈 수 있는 리뷰였습니다🙇🏻‍♀️ 함수마다 이름과 맡은 역할이 명확하게 정의되어 있고, 코드별로 주석을 꼼꼼하게 달아주셔서 이해하기 쉬웠습니다.
앞으로도 꾸준히 반복적으로 JS를 공부하는 모습 기대하겠습니다! (같이 공부해봐요!) 😀😀

Comment on lines +8 to +16
function getLocalStorageItem(key) {
return JSON.parse(localStorage.getItem(key)) || [];
}

// localStorage에 값을 새로 저장하는 함수
function setLocalStorageItem(key, data) {
localStorage.setItem(key, JSON.stringify(data));
}
Copy link
Member

Choose a reason for hiding this comment

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

localStorage에서 값을 가져오고 저장하는 일이 빈번한데, 이를 getter와 setter 메서드로 정리해서 코드 안전성/유지보수성을 높인 부분이 좋습니다!

Copy link
Author

Choose a reason for hiding this comment

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

처음 코드 작성 할 때부터 꼭 수정해봐야겠다고 생각했던 부분이라, 리팩토링 시 가장 우선순위로 두었던 것인데 드러난 것 같아 뿌듯합니다 🤩

function handleAddTodo() {
let inputValue = todoInput.value; // 입력한 todo 집중
if (!inputValue) return alert("내용을 입력해주세요!"); // 입력된 todo가 존재하지 않는다면 아무것도 하지 않기 위함
Copy link
Member

Choose a reason for hiding this comment

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

공백 문자 입력을 방지한 부분이 좋습니다👍🏻👍🏻

addTodoBtn.addEventListener("click", handleAddTodo); // +버튼에 todo 추가하는 함수 연결

function renderTodos() {
Copy link
Member

Choose a reason for hiding this comment

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

renderTodos라는 직관적인 함수명을 통해 해당 함수가 가진 역할(html 요소가 화면에 표시되는 것)을 바로 파악할 수 있어 좋습니다!🙌

Comment on lines +1 to +9
font-family: "KyoboHand";
src: url("https://fastly.jsdelivr.net/gh/projectnoonnu/[email protected]/KyoboHand.woff") format("woff");
font-weight: normal;
font-style: normal;
}
* {
font-family: "KyoboHand";
}
Copy link
Member

Choose a reason for hiding this comment

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

웹 폰트 적용한 부분 조아용~~

Comment on lines +10 to +20
body {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: radial-gradient(circle at 50% 0, rgba(255, 38, 38, 0.5), rgba(255, 0, 0, 0) 70.71%),
radial-gradient(circle at 6.7% 75%, rgba(30, 30, 255, 0.5), rgba(0, 0, 255, 0) 70.71%),
radial-gradient(circle at 93.3% 75%, rgba(63, 255, 63, 0.287), rgba(6, 26, 6, 0) 70.71%) beige;
}
Copy link
Member

Choose a reason for hiding this comment

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

배경색 오색찬란해서 마음에 듭니다🌈

Comment on lines +102 to +114
.scrollbar::-webkit-scrollbar {
width: 10px;
}

.scrollbar::-webkit-scrollbar-thumb {
background: rgba(220, 20, 60); /* 스크롤바 색상 */
border-radius: 10px; /* 스크롤바 둥근 테두리 */
}

.scrollbar::-webkit-scrollbar-track {
background: rgba(220, 20, 60, 0.1); /*스크롤바 뒷 배경 색상*/
}
Copy link
Member

Choose a reason for hiding this comment

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

오 스크롤바 디자인 방법 저도 알려주세요!

Copy link
Author

@ZUITOPIA ZUITOPIA Aug 29, 2024

Choose a reason for hiding this comment

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

링크

스크롤바 구현 자체는 여러번 해보았지만 커스텀 디자인을 해본 경험은 적어서 이번 기회를 통해 많은 글들을 찾아보았는데 그 중 가장 상세한 설명이 있는 글인 것 같아 공유합니다! 같이 공부해요 🙌

<div class="container">
<!-- <header>📚 투두리스트</header> -->
<header>
<img id="emoji" src="/images/emoji.png" alt="이모지" />
Copy link
Member

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