[1주차] 남기림 과제 제출합니다.#5
Conversation
waldls
left a comment
There was a problem hiding this comment.
기림님 1주차 과제하시느라 수고 많으셨습니다! 코드 보고 많이 배우고 갑니다 ㅎㅎ👍🏻👍🏻
현재 본문에 남겨주신 배포 링크의 텍스트와 실제 연결된 하이퍼주소 링크가 다른 것 같아요! 이 부분 더블체크 해주시면 좋을 것 같습니다 :)
| { | ||
| "name": "todo", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "vite", | ||
| "build": "vite build", | ||
| "preview": "vite preview" | ||
| }, | ||
| "devDependencies": { | ||
| "vite": "^8.0.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
Vite를 사용해서 세팅을 해주신 것으로 보입니다!
1주차 미션이 순수 Vanilla JS를 다루는 것이 목표인 만큼, package.json이나 vite.config.js 설정을 걷어내고 순수 환경을 깊게 다뤄보는 것도 좋은 경험이 될 것 같아요!
| <header> | ||
| <h1>TO DO LIST</h1> | ||
|
|
||
| <div class="date-btns"> | ||
| <button id="prev">◀</button> | ||
| <h2 id="date"></h2> | ||
| <button id="next">▶</button> | ||
| </div> | ||
| </header> | ||
|
|
||
| <main> | ||
| <section class="inputlist"> | ||
| <form> | ||
| <input | ||
| type="text" | ||
| id="todo-input" | ||
| placeholder="할 일을 입력하세요." | ||
| /> | ||
| <button id="add">추가</button> | ||
| </form> | ||
|
|
||
| <div>남은 TO DO의 개수: <span class="count">0</span>개</div> | ||
| </section> | ||
|
|
||
| <section> | ||
| <ul id="todo-list"></ul> | ||
| </section> | ||
| </main> |
There was a problem hiding this comment.
header, main, section 같은 시맨틱 태그를 적절히 활용해 주셔서 문서 구조가 한눈에 들어오네요! 특히 form 태그를 사용해 입력부를 구성하신 점이 인상 깊습니다ㅎㅎ
| const dayIndex = now.getDay(); | ||
| const shiftIndex = (dayIndex + 6) % 7; | ||
|
|
||
| const rainbowColors = [ | ||
| "#f9d6d6", | ||
| "#FFD6A5", | ||
| "#f8f9ca", | ||
| "#e7ffe2", | ||
| "#c7f4f8", | ||
| "#A0C4FF", | ||
| "#d1cafd", | ||
| ]; |
There was a problem hiding this comment.
요일별 배경색을 정하는 로직이 너무 센스있어요!! 👍🏻
다만 rainbowColors 배열은 유지보수를 위해 상수로 분리하는 것이 더 좋을 것 같습니다!
추후 색상을 수정하고 싶을 때 로직 내부를 뒤질 필요 없이 최상단의 상수값만 변경하면 되어 훨씬 편리할 것 같아요!
잘 알고 계시겠지만 제가 참고한 문서 링크 하나 남깁니다 ㅎㅎ
const RAINBOW_COLORS = ["#f9d6d6", "#FFD6A5", ...]; // 함수 밖 상단에 위치
const updateDisplay = () => {
const shiftIndex = (now.getDay() + 6) % 7;
const todayColor = RAINBOW_COLORS[shiftIndex];
// ...
};| const createTodoItem = (value, isDone = false) => { | ||
| const li = document.createElement("li"); | ||
| li.innerHTML = ` | ||
| <div class="output"> | ||
| <input class="check" type="checkbox" ${isDone ? "checked" : ""} /> | ||
| <span style="${isDone ? "text-decoration: line-through; color: gray;" : ""}">${value}</span> | ||
| <button class="delete"> - </button> | ||
| </div> | ||
| `; |
There was a problem hiding this comment.
현재 createTodoItem에서 innerHTML 과 템플릿 리터럴을 이용해 요소를 생성하고 계신데, 이 방식을 textContext으로 변경해보시는 건 어떨까요? 사용자 입력값이 HTML로 해석되는 걸 막아줘서 보안상으로도 훨씬 안전하다고 합니다!
자세한 차이점과 보안 이슈에 대해서는 기림님이 참고하시면 좋을 포스팅 링크도 함께 남겨드려요!
|
기림님 1주차 과제하시느라 고생 많으셨습니당! comment에 남겨주신 배포 링크가 제 컴퓨터에서는 오류가 떠서 확인이 어려워, 기림님 깃허브에 있는 배포 링크를 참고해서 코드 리뷰를 진행했습니다! |
| }; | ||
|
|
||
| const loadTodos = () => { | ||
| const savedTodos = JSON.parse(localStorage.getItem("myTodoList")) || []; |
There was a problem hiding this comment.
먼저 요일별로 지정된 배경 색상이 있어서 날짜를 넘길 때마다 시각적인 재미가 있고, 앱을 사용할 때 요일별로 배경이 바뀌는 것처럼 하루하루를 새로운 마음으로 지낼 수 있을 것 같아서 좋았습니당!
그리구 현재 localStorage.getItem("myTodoList")에서 key가 "myTodoList" 로 고정되어 있어서 날짜가 변경되더라도 동일한 todo 데이터가 로드됩니다.
_._.mp4
날짜별로 다른 todo 목록을 관리하려면localStorage.getItem(currentDate)처럼 key에 날짜 정보를 포함하는 방식도 참고하시면 좋을 것 같습니다!
Tutankhannun
left a comment
There was a problem hiding this comment.
이번 주차 과제 수고하셨습니다~~ 위트있는 기능도 추가해주시고 Pretendard 폰트 적용도 잘하셨네요. 다른 분들도 좋은 코드 리뷰들 남겨주셔서 잘 참고해주시고 담주 과제도 화이팅입니다!!
| li.querySelector(".check").onchange = (e) => { | ||
| const span = li.querySelector("span"); | ||
| if (e.target.checked) { | ||
| span.style.textDecoration = "line-through"; |
There was a problem hiding this comment.
완료 스타일에 인라인 js를 사용해주셨네요. 나중에 디자인을 수정하는 등의 유지 보수를 위해서는 css에서 클래스로 관리하는 게 깔끔할 것 같습니다!
| import "./style.css"; | ||
|
|
||
| const input = document.querySelector("#todo-input"); | ||
| //const addBtn = document.querySelector("#add"); |
There was a problem hiding this comment.
더 깔끔한 코드를 위해서 사용하지 않는 코드는 제거하는 것이 좋습니다!
| gap: 10px; | ||
| width: 100%; | ||
| max-width: 500px; | ||
| gap: 10px; |
| const countElement = document.querySelector(".count"); | ||
| const todoForm = document.querySelector("form"); | ||
|
|
||
| const now = new Date(); |
There was a problem hiding this comment.
최근 Date의 대채제로 이슈 중인 Temporal Api에 대해서도 한 번 읽어 보시면 좋을 것 같습니다~
Date는 사라지고 Temporal이 온다
| <body> | ||
| <div id="app"> | ||
| <header> | ||
| <h1>TO DO LIST</h1> |
There was a problem hiding this comment.
UI 상에서 다른 요소와 같이 해당 텍스트도 중앙 정렬해주셔도 좋을 것 같습니다.
배운 점 및 느낀 점
배포링크
https://vanilla-todo-23rd-ochre.vercel.app/
Review Questions
DOM이란 문서객체모델로, 웹 페이지를 스크립트 또는 프로그래밍 언어와 연결하는 역할을 합니다. 웹 브라우저는 HTML 문서를 해석하는 과정에서 문서객체모델을 생성합니다. 이는 HTML과 같은 문서 구조를 메모리에 표현함으로써 이루어집니다. DOM은 문서를 논리적 트리로 표현하는데, 트리의 각 가지는 노드에서 끝나고, 각 노드는 객체를 포함합니다. DOM 메서드를 사용하면 프로그래밍 방식으로 트리에 접근할 수 있습니다. 이를 통해 문서의 구조, 스타일, 또는 내용을 변경할 수 있습니다. 노드에는 이벤트 핸들러도 첨부될 수 있는데, 이벤트가 트리거되면 이벤트 핸들러가 실행됩니다.
코드 참고 및 출처: https://dsuumb.tistory.com/14