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주차] 이지수 미션 제출합니다. #3

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
22 changes: 18 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,26 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vanilla Todo</title>
<title>📚 TO DO LIST</title>
<link rel="stylesheet" href="style.css" />
</head>

<body>
<div class="container"></div>
<div class="container">
<header>📚 투두리스트</header>
<div class="input-container">
<input type="text" placeholder="할 일을 입력하세요" />
<button>+</button>
</div>
<div class="todo-list-container">
<h2>🗒️ TO DO (0)</h2>
<ul class="todo-list"></ul>
</div>
<div class="done-list-container">
<h2>💿 DONE (0)</h2>
<ul class="done-list"></ul>
</div>
</div>
<script src="script.js"></script>
</body>
<script src="script.js"></script>
</html>
</html>
92 changes: 91 additions & 1 deletion script.js
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
// 다들 화이팅!! ٩( *˙0˙*)۶
const todoInput = document.querySelector(".input-container input");
const addButton = document.querySelector(".input-container button");
const todoList = document.querySelector(".todo-list");
const doneList = document.querySelector(".done-list");
const todoCount = document.querySelector(".todo-list-container h2");
const doneCount = document.querySelector(".done-list-container h2");

let todoItems = [];
let doneItems = [];
Copy link
Member

Choose a reason for hiding this comment

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

값이 재할당 되지 않는 경우에는 const 키워드를 사용하는 게 좋습니다!


// 버튼 클릭 시 호출되는 이벤트 리스너를 설정
addButton.addEventListener("click", () => {
const task = todoInput.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() 사용하는 디테일 아주 좋네요!!

if (task) {
addTodoItem(task);
todoInput.value = ""; // 입력 필드 초기화
}
Comment on lines +13 to +17
Copy link

Choose a reason for hiding this comment

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

오호 addTodo 함수를 실행시키는 조건으로 truthy를 사용하는 방법이 있군요🫢
이게 훨씬 깔끔한 것 같아요! 참고하겠습니다^~^

});

// 새로운 할 일 항목을 배열에 추가
function addTodoItem(task) {
todoItems.push(task);
renderTodoList(); // 할 일 목록을 렌더링
}

// 지정된 인덱스의 항목을 배열에서 제거
function removeTodoItem(index) {
todoItems.splice(index, 1); // 인덱스에 해당하는 항목을 제거
renderTodoList(); // 업데이트된 할 일 목록을 렌더링
}
Comment on lines +20 to +30
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.

다른 분 리뷰에도 달아 놓긴 했는데, push()splice() 메서드보다는 spread 연산자 같이 원본 배열의 내용을 직접 변경하지 않는 방법을 사용하지 않는 것이 좋습니다!

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

간단히 설명드리자면, 배열의 값을 직접 변경할 경우 디버깅이 어렵고 의도치 않은 결과를 불러올 수 있기 때문에 배열의 값을 직접 변경하는 방식이 아닌 새로운 배열을 만들어 할당하는 방식을 추천합니다. 따라서 값을 직접 변경하는 push(), 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.

헉 제가 몰랐던 부분인 것 같습니다. 단순히 js 100제 문제풀면서 알게된 메소드를 적용해본다고 작성한 코드였는데! 알려주신 덕분에 배워갑니다!! 앞으로 어떤 메소드가 더 적절한지 고려하면서 코드를 작성하겠습니다!


// 항목을 완료 목록으로 이동
function completeTodoItem(index) {
const completedTask = todoItems.splice(index, 1); // 완료된 항목을 todoItems에서 제거
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()를 사용해 봅시다!

Copy link
Author

Choose a reason for hiding this comment

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

네넵!

doneItems.push(completedTask[0]); // 완료된 항목을 doneItems에 추가
renderTodoList(); // 할 일 목록을 렌더링
renderDoneList(); // 완료된 항목 목록을 렌더링
}

// done 목록에서 항목을 제거
function removeDoneItem(index) {
doneItems.splice(index, 1); // 인덱스에 해당하는 항목을 제거
renderDoneList(); // 업데이트된 완료된 항목 목록을 렌더링
}

// 할 일 목록을 화면에 렌더링
Copy link
Member

Choose a reason for hiding this comment

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

render() 함수를 따로 분리하여 작성하신 점도 너무 좋네요

function renderTodoList() {
todoList.innerHTML = ""; // 기존 목록 초기화
todoItems.forEach((item, 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() 사용 아주 좋습니다 👍🏻

const li = document.createElement("li");
li.textContent = item;

// 삭제 버튼 생성
const deleteBtn = document.createElement("span");
deleteBtn.textContent = "🗑️";
deleteBtn.classList.add("delete-btn");
deleteBtn.addEventListener("click", () => removeTodoItem(index));

// 완료 버튼 생성
const completeBtn = document.createElement("span");
completeBtn.textContent = "✔️";
completeBtn.classList.add("complete-btn");
completeBtn.addEventListener("click", () => completeTodoItem(index));
Comment on lines +57 to +63

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.

저도 화살표 함수 어려웠는데 이번 기회에 한번 작성해보쟈!했던 것 같아요! 감사합니다!!


li.appendChild(completeBtn);
li.appendChild(deleteBtn);
todoList.appendChild(li);
});
// 할 일 항목 수를 업데이트
todoCount.textContent = `🗒️ TO DO (${todoItems.length})`;
}

// 완료된 항목 목록을 화면에 렌더링
function renderDoneList() {
Copy link
Member

Choose a reason for hiding this comment

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

renderDoneList() 함수도 결국 renderTodoList()와 동일하게 투두 아이템을 화면에 그리는 역할을 하니, 한 단계 더 추상화하여 하나의 함수로 작성해 보는 것도 좋을 것 같아요 👍🏻

Copy link
Author

@jissssu jissssu Aug 29, 2024

Choose a reason for hiding this comment

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

헉 이 부분도 고민이였던 것 중에 하나였어요! 이또한 충분히 고민해보고 반영하도록 하겠습니다!

doneList.innerHTML = ""; // 기존 목록 초기화
doneItems.forEach((item, index) => {
const li = document.createElement("li");
li.textContent = item;

// 삭제 버튼 생성
const deleteBtn = document.createElement("span");
deleteBtn.textContent = "🗑️";
deleteBtn.classList.add("delete-btn");
deleteBtn.addEventListener("click", () => removeDoneItem(index));

li.appendChild(deleteBtn);
doneList.appendChild(li);
});
// 완료된 항목 수를 업데이트
doneCount.textContent = `💿 DONE (${doneItems.length})`;
}
75 changes: 74 additions & 1 deletion style.css
Original file line number Diff line number Diff line change
@@ -1 +1,74 @@
/* 자유롭게 디자인 해 주세요! */
/* 자유롭게 디자인 해 주세요! */

body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
Copy link

Choose a reason for hiding this comment

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

CSS 단위 하나 알고갑니다..! 고정값으로 컨테이너를 배열했는데 vh를 사용해봐야겠어요🤩

Copy link
Author

Choose a reason for hiding this comment

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

저도 이번에 새로운것도 적용해보쟈해서 작성했는데! 같이 배워가니 너무 좋습니다!

background: linear-gradient(to right, #d8bfd8, #ffb6c1);
}

.container {
background: white;
border-radius: 10px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
padding: 20px;
width: 300px;
}

header {
font-size: 24px;
margin-bottom: 20px;
text-align: center;
}

.input-container {
display: flex;
gap: 10px;
margin-bottom: 20px;
}

input[type="text"] {
flex-grow: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}

button {
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}

.todo-list-container, .done-list-container {
margin-top: 20px;
}

ul {
list-style-type: none;
}

li {
display: flex;
justify-content: space-evenly;
align-items: baseline;
padding: 10px;
border-bottom: 1px solid #ccc;
margin-right: 40px;
}

li .delete-btn {
cursor: pointer;
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 +64 to +65

Choose a reason for hiding this comment

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

Suggested change
li .delete-btn {
cursor: pointer;
li:hover {
cursor: pointer;

이렇게 변경하면 모든 li 항목에 대해서 cursor: pointer를 할 수 있을 것같아요!

Copy link
Author

Choose a reason for hiding this comment

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

헉! 네네 당장 수정해보도록 하겠습니다! 알려주셔서 감사해요!

color: red;
}

h2 {
font-size: 18px;
margin-bottom: 10px;
}