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주차] 김동혁 미션 제출합니다. #2

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
81 changes: 49 additions & 32 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,51 @@ document.addEventListener("DOMContentLoaded", function () {

// 로컬 스토리지에서 할 일 목록을 불러와서 페이지에 추가
const toDos = JSON.parse(localStorage.getItem("toDos")) || [];
Copy link
Member

Choose a reason for hiding this comment

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

로컬 스토리지까지 정말 짱입니다~!

toDos.forEach((todo) => {
addTodoItem(todo, false); // 이미 저장된 항목을 불러오므로, 여기서는 save 파라미터를 false로 설정
toDos.forEach((todoObj) => {
addTodoItem(todoObj, false); // 이미 저장된 항목을 불러오므로, 여기서는 save 파라미터를 false로 설정
Copy link

Choose a reason for hiding this comment

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

저는 새로 추가된 리스트는 클래스 이름을 별개로 주는 방식으로 기존의 리스트와 구분을 했는데요, 그래서 코드가 복잡했던 것 같아요 🥹
그런데 요렇게 함수의 받아오는 인자를 여러 개 두는 것으로 구분하니까 훨씬 간결하고 좋네요 > <

리팩토링할 때 도움이 될 것 같아요 ㅎㅎ 많이 배웁니당

});
}

// 할 일 추가
function addTodoItem(todoText, save = true) {
function addTodoItem(todoObj, save = true) {
const todoItem = document.createElement("li");
todoItem.classList.add("animate-slide-down");

const todoTextContent = document.createElement("span");
todoTextContent.textContent = todoText;
todoTextContent.textContent = todoObj.text;

// 체크 상태
if (todoObj.checked) {
todoTextContent.style.textDecoration = "line-through";
todoItem.style.color = "#808080";
} else {
todoTextContent.style.textDecoration = "none";
todoItem.style.color = "white";
}
Comment on lines +40 to +46
Copy link

Choose a reason for hiding this comment

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

className을 가지고 스타일 변경은 css로 빼서 쓰면 더 가독성이 좋을 것 같아요! ☺️


// 체크 상태 변경
const completeCheck = document.createElement("img");
completeCheck.src = todoObj.checked
? "./icon/checkComplete.svg"
Copy link
Member

Choose a reason for hiding this comment

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

완료한 일에 따라 다른 아이콘으로 표시해준 것은 좋지만, 완료된 일은 위치를 아래쪽으로 변경해주는 등 위치변경이 있었으면 더 좋았을 것 같습니다~!

: "./icon/NotCheck.svg";
Comment on lines +49 to +52
Copy link

Choose a reason for hiding this comment

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

삼항연산자로 코드가 훨씬 깔끔해졌네요 ㅎㅎ

completeCheck.style.cursor = "pointer";

completeCheck.onclick = function () {
todoObj.checked = !todoObj.checked;
Copy link

Choose a reason for hiding this comment

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

이것도 저는 클래스를 두어 할일과 끝낸일을 구분했는데 todoObj를 객체로 저장해서 체크 여부를 구분하는 아이디어가 너무 좋은 것 같아요 👍

completeCheck.src = todoObj.checked
? "./icon/checkComplete.svg"
: "./icon/NotCheck.svg";
if (todoObj.checked) {
todoTextContent.style.textDecoration = "line-through";
todoItem.style.color = "#808080";
} else {
todoTextContent.style.textDecoration = "none";
todoItem.style.color = "white";
}
saveTodoToStorage(todoObj); // 체크 상태 변경 후 저장
};

// 삭제 버튼
// 할 일 삭제
const deleteButton = document.createElement("button");
deleteButton.textContent = "삭제";
deleteButton.onclick = function () {
Expand All @@ -45,52 +76,37 @@ document.addEventListener("DOMContentLoaded", function () {

todoItem.addEventListener("animationend", () => {
Copy link

Choose a reason for hiding this comment

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

animationend를 사용해 애니메이션이 끝날 때 함수들이 실행돼서 좋은거 같아요.

todoList.removeChild(todoItem);
removeTodoFromStorage(todoText);
removeTodoFromStorage(todoObj.text);
});
};

// 완료 체크 이미지 생성
const completeCheck = document.createElement("img");
completeCheck.src = "./icon/NotCheck.svg";
completeCheck.style.cursor = "pointer";
completeCheck.setAttribute("data-checked", "false");

completeCheck.onclick = function () {
const isChecked = this.getAttribute("data-checked") === "true";
if (isChecked) {
this.src = "./icon/NotCheck.svg";
this.setAttribute("data-checked", "false");
todoTextContent.style.textDecoration = "none";
todoItem.style.color = "white";
} else {
this.src = "./icon/checkComplete.svg";
this.setAttribute("data-checked", "true");
todoTextContent.style.textDecoration = "line-through";
todoItem.style.color = "#808080";
}
};

todoList.insertBefore(todoItem, todoList.firstChild);
todoItem.appendChild(completeCheck);
todoItem.appendChild(todoTextContent);
todoItem.appendChild(deleteButton);

if (save) {
saveTodoToStorage(todoText);
saveTodoToStorage(todoObj);
}
}

// 로컬 스토리지에 할 일 저장
function saveTodoToStorage(todoText) {
function saveTodoToStorage(todoObj) {
const toDos = JSON.parse(localStorage.getItem("toDos")) || [];
toDos.push(todoText);

const index = toDos.findIndex((todo) => todo.text === todoObj.text);
if (index !== -1) {
toDos[index] = todoObj; // 기존 항목 업데이트
Comment on lines +98 to +99
Copy link

@songess songess Mar 16, 2024

Choose a reason for hiding this comment

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

value가 중복되는 것까지 체크하는 것 까지 구현한게 멋져요!
다만 83번 문에서 todoList에 insert하는 과정은 중복체크와 관계없이 항상 실행되어서 페이지를 새로고침하기 전까지는 화면에 중복되는 value가 포함된 div카드가 보이는 것 같아요.

} else {
toDos.push(todoObj); // 할 일 추가
}
localStorage.setItem("toDos", JSON.stringify(toDos));
}

// 로컬 스토리지에서 할 일 삭제
function removeTodoFromStorage(todoText) {
const toDos = JSON.parse(localStorage.getItem("toDos")) || [];
const updatedToDos = toDos.filter((todo) => todo !== todoText);
const updatedToDos = toDos.filter((todo) => todo.text !== todoText);
localStorage.setItem("toDos", JSON.stringify(updatedToDos));
}

Expand All @@ -99,7 +115,8 @@ document.addEventListener("DOMContentLoaded", function () {
e.preventDefault();
const todoText = inputField.value.trim();
Copy link
Member

Choose a reason for hiding this comment

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

trim()을 사용해 아무것도 입력되지 않을 때 리스트가 추가되지 않도록 꼼꼼하게 신경써주신 것 좋습니다~!

Copy link
Member

Choose a reason for hiding this comment

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

alert()를 함께 띄워줘도 좋을 것 같아요ㅎㅎ

if (todoText !== "") {
addTodoItem(todoText);
const todoObj = { text: todoText, checked: false };
Copy link

Choose a reason for hiding this comment

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

localstorage에 저장되는 todo값을 객체배열형태로 저장해 하나의 키 값만을 활용해 완료/미완료 todo를 관리할 수 있어서 좋은거 같아요!

addTodoItem(todoObj);
inputField.value = "";
Copy link

Choose a reason for hiding this comment

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

유효성 검사까지 해서 좋아요!
else문까지 작성해서 빈 문자열이 들어오면 다시 입력하라는 알림창도 있으면 좋을거 같아요.

Copy link
Member Author

Choose a reason for hiding this comment

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

빈 문자열일때는 투두추가 함수 작동이 안되도록 설정했어요!

}
});
Expand Down