-
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주차] 김류원 미션 제출합니다. #10
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,119 @@ | ||
//😍CEOS 20기 프론트엔드 파이팅😍 | ||
const addBtn = document.querySelector('.addBtn'); | ||
const TodoInput = document.querySelector('.TodoInput'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기서도 |
||
const todoList = document.querySelector('.todoList'); | ||
const todoForm = document.getElementById('todoForm'); | ||
|
||
let todos = []; | ||
|
||
// localStorage에서 todos 불러오기 | ||
function loadTodos() { | ||
const savedTodos = localStorage.getItem('todos'); | ||
if (savedTodos) { | ||
todos = JSON.parse(savedTodos); | ||
todos.forEach(todo => createTodoElement(todo.text, todo.completed)); | ||
} | ||
} | ||
|
||
// localStorage에 todos 저장 | ||
function saveTodos() { | ||
localStorage.setItem('todos', JSON.stringify(todos)); | ||
} | ||
|
||
function addTodo(e) { | ||
e.preventDefault(); | ||
|
||
const Todo = TodoInput.value.trim(); | ||
|
||
if (Todo) { | ||
createTodoElement(Todo, false); | ||
todos.push({ text: Todo, completed: false }); | ||
saveTodos(); | ||
TodoInput.value = ''; | ||
} else { | ||
alert('To Do를 입력하세요'); | ||
} | ||
Comment on lines
+27
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 항목이 존재하지 않을 때, 에러 핸들링를 해주신건 사용자입장에서 정말 좋을거같아요! |
||
} | ||
|
||
todoForm.addEventListener('submit', addTodo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
// 투두 추가 함수 | ||
function createTodoElement(Todo, isCompleted) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. createTodoElement() 함수 내에 투두 텍스트 생성 / 토글 생성 / 삭제 버튼 생성 로직을 별도의 함수로 빼낸 후, |
||
const listItem = document.createElement('li'); | ||
listItem.classList.add('animate-slide-down'); | ||
|
||
if (isCompleted) { | ||
listItem.classList.add('completed'); | ||
} | ||
|
||
// 완료 토글 아이콘 | ||
const toggleIcon = document.createElement('img'); | ||
toggleIcon.src = isCompleted ? './icon/checkComplete.svg' : 'https://raw.githubusercontent.com/ryu-won/vanilla-todo-20th/40e5a4dcd0113eadd85034cc953aa3fa97de4527/icon/NotCheck.svg'; | ||
toggleIcon.alt = isCompleted ? 'Toggle Complete' : 'Toggle unComplete'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
toggleIcon.classList.add('toggle-icon'); | ||
|
||
// 투두 텍스트 | ||
const todoText = document.createElement('span'); | ||
todoText.textContent = Todo; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 변수명을 쓸 때, Todo보다 lowercamelcase 컨벤션에 맞추어 todo로 작성하는것이 좋을 것 같아요! |
||
if (isCompleted) { | ||
todoText.classList.add('completed-text'); | ||
} | ||
|
||
toggleIcon.addEventListener('click', () => { | ||
listItem.classList.toggle('completed'); | ||
todoText.classList.toggle('completed-text'); | ||
const isNowCompleted = listItem.classList.contains('completed'); | ||
if (isNowCompleted) { | ||
toggleIcon.src = './icon/checkComplete.svg'; | ||
toggleIcon.alt = 'Toggle Complete'; | ||
} else { | ||
toggleIcon.src = 'https://raw.githubusercontent.com/ryu-won/vanilla-todo-20th/40e5a4dcd0113eadd85034cc953aa3fa97de4527/icon/NotCheck.svg'; | ||
toggleIcon.alt = 'Toggle unComplete'; | ||
Comment on lines
+69
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이미지 소스를 가져올 때 주소가 하드코딩 되어있는데 나중에 쉽게 관리할 수 있도록 아래와 같이 상수로 분리하는 방법도 있을 것 같습니다! const NOT_CHECK = 'https://raw.githubusercontent.com/.../NotCheck.svg'; 이렇게 하면 해당 이미지를 중복적으로 사용할 때, 이미지 경로를 변경 시 코드 전체에서 한 번만 수정하면 되고, 에러 찾기도 더 쉽지 않을까 생각합니다 😊 |
||
} | ||
// localStorage 업데이트 | ||
const index = todos.findIndex(item => item.text === Todo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 류원님의 투두 리스트에서 동일한 내용을 가진 항목을 추가하고, 완료하면 첫번째 항목의 completed 값만 true로 변경되고 두번째 항목의 completed 값은 변경되지 않는 것을 확인할 수 있어요. 지금 코드를 보면, 항목을 고유하게 식별할 수 있는 값이 없고, 텍스트만을 기준으로 항목을 찾고 업데이트하는 것으로 보여요. 때문에, 텍스트가 동일한 두 항목이 있을 경우 제대로 구분되지 않고 한 항목만 업데이트되는 문제가 발생하는 것 같아요. 이러한 문제를 해결하려면, 각각의 항목을 텍스트 내용에 상관없이 고유하게 식별할 수 있어야 하는데, text를 구분 기준으로 삼기 보다, 고유한 id를 추가해서 Id를 기준으로 식별하는 것이 좋아보여요!
-> ... 이런식으로요! https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex |
||
if (index !== -1) { | ||
todos[index].completed = isNowCompleted; | ||
saveTodos(); | ||
} | ||
}); | ||
|
||
// 삭제 버튼 | ||
const deleteBtn = document.createElement('button'); | ||
deleteBtn.textContent = 'Del'; | ||
deleteBtn.classList.add('delete-btn'); | ||
deleteBtn.addEventListener('click', () => { | ||
listItem.classList.add('animate-fade-out'); | ||
setTimeout(() => { | ||
todoList.removeChild(listItem); | ||
// localStorage에서 삭제 | ||
todos = todos.filter(item => item.text !== Todo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 할일 항목을 삭제할때도, 텍스트 기준으로 비교되어서 |
||
saveTodos(); | ||
}, 300); | ||
}); | ||
|
||
listItem.appendChild(toggleIcon); | ||
listItem.appendChild(todoText); | ||
listItem.appendChild(deleteBtn); | ||
Comment on lines
+94
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 |
||
todoList.appendChild(listItem); | ||
} | ||
|
||
// 날짜 표시 함수 | ||
function formatDateKorean(date) { | ||
const days = ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일']; | ||
const months = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']; | ||
Comment on lines
+102
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 상수를 선언해 주신 점 좋습니다👍 |
||
|
||
const month = months[date.getMonth()]; | ||
const day = date.getDate(); | ||
const dayOfWeek = days[date.getDay()]; | ||
|
||
return `${month} ${day}일 ${dayOfWeek}`; | ||
} | ||
Comment on lines
+101
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
// 페이지 로드 시 실행 | ||
document.addEventListener('DOMContentLoaded', () => { | ||
const todayDateElement = document.getElementById('todayDate'); | ||
const today = new Date(); | ||
todayDateElement.textContent = formatDateKorean(today); | ||
|
||
loadTodos(); // localStorage에서 todos 불러오기 | ||
}); |
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.
WriteForm
이나TodoInput
,check_icon
에서 네이밍 컨벤션이 다른 부분이 보이는데, 혹시 의도하신걸까요?!