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 4 commits into
base: master
Choose a base branch
from

Conversation

wokbjso
Copy link

@wokbjso wokbjso commented Sep 14, 2023

배포 링크: https://vanilla-todo-18th.vercel.app/

1주차 과제로 투두리스트 만들기를 구현해보았습니다.

인풋에 todo를 입력 후 엔터 혹은 버튼을 누르면 todo가 추가됩니다. 투두가 추가될 때 동적으로 체크박스와 인풋에 입력한 값, 그리고 투두를 삭제할 수 있는 버튼을 만들어서 인풋 아래에 차례대로 뿌려줍니다.
체크박스를 누르면 해당 일을 다 했다는 의미로 줄이 그어지며 x 버튼을 누르면 해당 todo가 삭제됩니다.
전체 todo의 개수를 띄워주며 체크박스가 눌린 todo의 개수는 완료로, 안눌린 todo의 개수는 진행중으로 분류되어 보여줍니다.
해당 todo의 텍스트와 체크의 여부를 묶어 객체로 관리하여 todo가 추가되거나 체크 상태가 변할 때, 혹은 삭제될 때 마다 localStorage 에 해당 사항을 업데이트하여 저장합니다.
localStorage 에 저장했기 때문에 새로고침해도 해당 todo의 상태와 값이 그대로 보여지게 됩니다.

media-query 를 적용 후 rem 단위로 작업하여 모바일부터 pc 까지 문제없이 활용할 수 있도록 작업하였습니다.

사실 그렇게 어렵지 않은 과제라고 생각을 했지만, 오히려 초심으로 돌아가려니까 생각보다 헤맸던 부분이 꽤 있었습니다. 너무 React 에 익숙해진 탓에 class 및 id 이름을 직접 생성하여 css 파일에 적용하고, addEventListener 를 적용하는 등 오랫동안 하지 않았던 방식으로 코딩을 하니 어색함을 느꼈고, 기본기가 좀 부족하다는 것을 느끼고 반성도 하게되는 시간이였습니다.

사실 깔끔하게 기능단위로 커밋을 날렸어야 했는데 까먹고 본의아니게 완성후 커밋을 날렸다.. 앞으로는 기능단위로 커밋을 날려 코드리뷰도 편하게 할 수 있도록 작업하도록 하겠습니다 죄송합니다 ㅠㅠ

  1. DOM은 무엇인가요?
  • DOM은 문서 객체 모델(Document Object Model) 로 HTML문서를 브라우저가 이해할 수 있도록 만든 Tree 자료구조이다. 내가 이해한 바로는 예를 들어 main, header, div, span 태그 등의 semantic tag 들을 사용하는 과정에서 이 태그들은 부모와 자식 형태의 관계를 갖게 되는데 이를 Tree 형태의 구조로 나타낸 것을 DOM 이라고 한다.

우리가 프로젝트를 하면서 코드를 수정하게 되면 이 DOM 구조에 접근하여 수정된 태그에 접근을 하여 업데이트 하게 되는데 수정사항이 있을 때마다 DOM 에 직접 접근하는 것은 매우 비효율적이다. 따라서 React와 Vue 등은 Virtual DOM 을 활용한다. 수정 전의 Virtual DOM 과 수정하려는 Virtual DOM 의 비교과정을 거친 후 변경된 태그들만 DOM에 직접 접근하여 업데이트를 해주는 방식으로 매우 효율적인 방식이라고 알고 있다.

  1. HTML (tag) Element를 JavaScript로 생성하는 방법은 어떤 것이 있고, 어떤 방법이 가장 적합할까요?
  • 우선 가장 보편적으로 사용하는 방식으로는 document.createElement() 라는 함수를 사용한다. 함수 괄호 안에 "div", "span" 등의 태그를 입력하여 해당 태그의 Element를 생성한다
    또한 알아본 바로 HTMLElement.insertAdjacentHTML() 라는 함수를 사용하기도 한다. "beforebegin", "afterbegin", "beforeend", "afterend"와 같이 위치를 지정하는 옵션을 활용하여 요소 내에 HTML을 삽입할 때 사용된다.

insertAdjacentHTML 함수는 XSS공격 등 보안에 취약하다는 단점이 있고, createElement 함수가 동적으로 요소를 간단히 생성할 수 있다는 장점이 커서 createElement 함수를 사용하는 것이 적합하다고 판단된다.

  1. Semantic tag에는 어떤 것이 있으며, 이를 사용하는 이유는 무엇일까요?
  • Sementic tag는 의미가 있는 tag 로 HTML 요소에서 , , 등의 태그를 Semantic tag 라고 한다. Semantic tag를 사용하는 가장 큰 이유는 코드의 가독성 때문이다. 모든 웹사이트를 div 태그를 남발하여 사용해도 아무 문제가 없지만, 그렇게 되면 어디서부터 어디까지가 header인지, 어디가 footer 인지 잘 알아볼 수가 없을 것이기 때문에 의미가 있는 tag를 적극적으로 사용하는 것이 유지보수에 좋다고 생각된다.

또한 검색엔진은 태그를 기반으로 페이지 내 검색 키워드의 우선순위를 판단하므로 Semantic tag를 적극 활용하는 것이 검색엔진을 최적화 시키는 방법 중 하나일 수 있다.

  1. Flexbox Layout은 무엇이며, 어떻게 사용하나요?
  • Flexbox Layout 이란 HTML 요소들을 화면내에 쉽게 배치하기 위해 활용하는 CSS 문법이다. 부모 요소에 display:flex 를 선언하면 Flexbox Layout 을 사용할 수 있고, 선언 시 자식 요소들은 모두 수평으로 배열되게 된다. 그 이후 자식 요소의 수평 배치를 위해 사용되는 문법인 justify-content 와, 자식 요소의 수직 배치를 위해 사용되는 문법인 align-items를 활용하여 자식 요소들을 알맞게 배치한다.

display:flex 로 수평배열 된 자식 요소들을 기본적으로 수직배열되게 하고 싶다면 flex-direction:column 을 활용한다. 이를 활용하게 되면 위와 반대로 justify-content 문법이 자식 요소들의 수직 배치를, align-items 문법은 자식 요소들의 수평 배치를 맡게 된다. 또한 space-between, flex-start, space-around 등 세부적으로도 배치를 조절할 수 있다.

  1. JavaScript가 다른 언어들에 비해 주목할 만한 점에는 어떤 것들이 있나요?
  • 생태계가 넓은 만큼 많은 장점들을 가지고 있겠지만 내가 주목한 점은 변수 선언이였다. 데이터의 타입을 선언해준 뒤 사용하는 대부분의 언어와 달리 자바스크립트는 대부분의 경우 const 하나로 변수 사용이 가능했다. 정수, 배열, 객체 가리지 않고 모두 const 로 선언하여 사용하면 변수의 데이터 타입을 런타임 시에 결정하게되고, 이 특징 매우 유연하게 개발을 할 수 있도록 도와주었다.

또한 전세계에서 사랑받는 언어로 모르는 부분이 있을 때 구글링을 하면 자료가 매우 방대하여 빠르게 해결할 수 있다는 것도 큰 장점이다. 이처럼 자바스크립트는 매우 유연한 코딩을 도와주고 넓은 생태계 등의 장점을 가지고 있다.

  1. 코드에서 주석을 다는 바람직한 방법은 무엇일까요?
  • 개인적으로 큰 단계별로 주석을 달거나 상대방이 이해하기 힘들 것 같은 코드, 혹은 중요한 기능을 포함하고 있는 코드에 주석을 다는 것이 바람직하다고 생각한다.
    이러한 코드들에 주석을 달아준다면 상대방의 수월한 코드리뷰를 이끌어낼 수 있고, 추후에 리팩토링 및 유지보수를 할 때에도 주석을 읽으며 코드를 보면 훨씬 더 빠른 작업을 할 수 있다고 생각을 하기 때문에 이렇게 주석을 단다면 좋을 것 같다.

@wokbjso wokbjso changed the title 1주차 김현민 미션 제출합니다. [1주차] 김현민 미션 제출합니다. Sep 14, 2023
Copy link
Collaborator

@westofsky westofsky left a comment

Choose a reason for hiding this comment

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

안녕하세요 프론트 운영진 배성준입니다~~!!!!!!!!!!!!!!!!!!

첫 과제 너무 고생하셨어요~~ trim도 사용하시고 반응형도 고려하신 것 같아 되게 꼼꼼하신것같습니다~~ media query나 rem을 자유자재로 잘 사용하시는 것 같아 부러워요 .. 배워갑니다
제가 약간 코멘트 달았는데 참고해주시면 될 것 같아요!! 고생하셨습니다~~

Comment on lines +176 to +177
font-weight: 500;
font-weight: 600;
Copy link
Collaborator

Choose a reason for hiding this comment

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

두개 합치면 1100 !?!!?!?!?!?!

Comment on lines +81 to +104
addTodo.addEventListener("click", () => {
const text = todoInput.value.trim(); //입력한 todo의 불필요한 공백 제거
if (text) {
const newTodo = { text, checked: false }; //입력된 text와, 초기에 check은 false이므로 해당 상태를 변수로 선언
storedTodos.push(newTodo); //현재 todo를 저장하는 배열 변수에 push
saveTodos(); //push된 배열 변수의 상태를 localStorage에 update
addTodoItem(newTodo); //현재 입력한 todo의 상태를 화면에 보여주도록 선언한 addTodoItem에 전달
todoInput.value = ""; //입력을 완료하면 현재 input 값 빈 string으로 선언
}
});

//PC에서의 편리한 사용을 고려하여 엔터를 눌러도 해당 함수가 trigger 되게 addEventListener 등록
todoInput.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
const text = todoInput.value.trim();
if (text) {
const newTodo = { text, checked: false };
storedTodos.push(newTodo);
saveTodos();
addTodoItem(newTodo);
todoInput.value = "";
}
}
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

이벤트리스너의 콜백함수를 따로 빼서 관리해도 좋을 것 같아요!

Suggested change
addTodo.addEventListener("click", () => {
const text = todoInput.value.trim(); //입력한 todo의 불필요한 공백 제거
if (text) {
const newTodo = { text, checked: false }; //입력된 text와, 초기에 check은 false이므로 해당 상태를 변수로 선언
storedTodos.push(newTodo); //현재 todo를 저장하는 배열 변수에 push
saveTodos(); //push된 배열 변수의 상태를 localStorage에 update
addTodoItem(newTodo); //현재 입력한 todo의 상태를 화면에 보여주도록 선언한 addTodoItem에 전달
todoInput.value = ""; //입력을 완료하면 현재 input 값 빈 string으로 선언
}
});
//PC에서의 편리한 사용을 고려하여 엔터를 눌러도 해당 함수가 trigger 되게 addEventListener 등록
todoInput.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
const text = todoInput.value.trim();
if (text) {
const newTodo = { text, checked: false };
storedTodos.push(newTodo);
saveTodos();
addTodoItem(newTodo);
todoInput.value = "";
}
}
});
addButton.addEventListener("click", handleAddTodo);
inputElement.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
handleAddTodo();
}
});
function handleAddTodo() {
const text = inputElement.value.trim();
if (text) {
const newTodo = { text, checked: false };
storedTodos.push(newTodo);
saveTodos();
addTodoItem(newTodo);
inputElement.value = "";
}
}

Comment on lines +57 to +66
.deleteBtn {
background-color: transparent;
display: flex;
justify-content: center;
align-items: center;
margin-left: 1rem;
border: none;
font-size: 4rem;
color: gray;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

유저가 클릭해서 action을 취할 수 있는 부분에 대해서는 cursor : pointer 을 주는 것도 좋을 것 같아요

Comment on lines +66 to +68
todoItem.appendChild(checkbox);
todoItem.appendChild(todoText);
todoItem.appendChild(deleteButton);
Copy link
Collaborator

Choose a reason for hiding this comment

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

appendChild를 append를 이용하여 작성할 수도 있어요! 한번 블로그글 이것도 참고해보면 좋을 것 같아요

Comment on lines +12 to +14
function saveTodos() {
localStorage.setItem("todos", JSON.stringify(storedTodos));
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

선택사항인 로컬스토리지도 구현하셨네요!!!!!!!!!!!!!!!!!!!! 굿입니다

Comment on lines +33 to +64
function addTodoItem(todo) {
const todoItem = document.createElement("div");
todoItem.classList.add("todoWrapper");

const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.classList.add("todoCheckbox");
checkbox.checked = todo.checked || false; //전달받은 todo의 check 상태가 true면 true, 아니면 false로 선언
checkbox.addEventListener("change", () => {
todo.checked = checkbox.checked; //해당 todo의 체크박스 상태가 변하면 그 상태를 저장해 준 후
saveTodos(); //localStorage의 체크박스 상태 변화 저장
todoText.style.textDecoration = checkbox.checked ? "line-through" : "none"; //체크박스가 check 되어있다면 해당 todo에 줄 그어줌
updateCheckedTodoCount(); //해당 todo의 체크 상태가 변했으므로 진행중인 todo와 완료된 todo개수 update
});

const todoText = document.createElement("div");
todoText.textContent = todo.text; //불러온 todo의 text 값을 생성한 요소에 저장
todoText.classList.add("todoText");
todoText.style.textDecoration = todo.checked ? "line-through" : "none"; //불러온 todo의 체크 상태에 따라 줄을 그을지 말지 판단

const deleteButton = document.createElement("button");
deleteButton.classList.add("deleteBtn");
deleteButton.textContent = "X";
//각 todo의 X 버튼을 누르면 trigger
deleteButton.addEventListener("click", () => {
const index = storedTodos.indexOf(todo); //전체 todo 상태가 저장되어 있는 배열에서 해당 todo의 index 값 불러옴
storedTodos.splice(index, 1); //해당 index부터 1개의 요소 삭제(즉, 해당 todo만 삭제)
saveTodos(); //삭제된 상태를 localStorage 에 update
todoList.removeChild(todoItem); //해당 todo를 화면에서 지워줌
updateTotalTodoCount(); //전체 todo 개수 update
updateCheckedTodoCount(); //진행중 및 완료 todo 개수 update
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

addTodoItem 이라는 함수가 어떤 로직을 처리하는지 한 눈에 볼 수 있도록 각 checkbox,todoText,deleteButton을 만드는 함수를 따로 처리하면 가독성이나 유지보수 측면에서도 좋을 것 같아요!

Suggested change
function addTodoItem(todo) {
const todoItem = document.createElement("div");
todoItem.classList.add("todoWrapper");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.classList.add("todoCheckbox");
checkbox.checked = todo.checked || false; //전달받은 todo의 check 상태가 true면 true, 아니면 false로 선언
checkbox.addEventListener("change", () => {
todo.checked = checkbox.checked; //해당 todo의 체크박스 상태가 변하면 그 상태를 저장해 준 후
saveTodos(); //localStorage의 체크박스 상태 변화 저장
todoText.style.textDecoration = checkbox.checked ? "line-through" : "none"; //체크박스가 check 되어있다면 해당 todo에 줄 그어줌
updateCheckedTodoCount(); //해당 todo의 체크 상태가 변했으므로 진행중인 todo와 완료된 todo개수 update
});
const todoText = document.createElement("div");
todoText.textContent = todo.text; //불러온 todo의 text 값을 생성한 요소에 저장
todoText.classList.add("todoText");
todoText.style.textDecoration = todo.checked ? "line-through" : "none"; //불러온 todo의 체크 상태에 따라 줄을 그을지 말지 판단
const deleteButton = document.createElement("button");
deleteButton.classList.add("deleteBtn");
deleteButton.textContent = "X";
//각 todo의 X 버튼을 누르면 trigger
deleteButton.addEventListener("click", () => {
const index = storedTodos.indexOf(todo); //전체 todo 상태가 저장되어 있는 배열에서 해당 todo의 index 값 불러옴
storedTodos.splice(index, 1); //해당 index부터 1개의 요소 삭제(즉, 해당 todo만 삭제)
saveTodos(); //삭제된 상태를 localStorage 에 update
todoList.removeChild(todoItem); //해당 todo를 화면에서 지워줌
updateTotalTodoCount(); //전체 todo 개수 update
updateCheckedTodoCount(); //진행중 및 완료 todo 개수 update
});
function createCheckbox(checked) {
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.classList.add("todoCheckbox");
checkbox.checked = checked || false;
checkbox.addEventListener("change", handleCheckboxChange);
return checkbox;
}
function createTodoText(text, checked) {
const todoText = document.createElement("div");
todoText.textContent = text;
todoText.classList.add("todoText");
todoText.style.textDecoration = checked ? "line-through" : "none";
return todoText;
}
function createDeleteButton(todo, todoItem) {
const deleteButton = document.createElement("button");
deleteButton.classList.add("deleteBtn");
deleteButton.textContent = "X";
deleteButton.addEventListener("click", () => {
const index = storedTodos.indexOf(todo); //전체 todo 상태가 저장되어 있는 배열에서 해당 todo의 index 값 불러옴
storedTodos.splice(index, 1); //해당 index부터 1개의 요소 삭제(즉, 해당 todo만 삭제)
saveTodos(); //삭제된 상태를 localStorage 에 update
todoList.removeChild(todoItem); //해당 todo를 화면에서 지워줌
updateTotalTodoCount(); //전체 todo 개수 update
updateCheckedTodoCount(); //진행중 및 완료 todo 개수 update
});
return deleteButton;
}
function addTodoItem(todo){
const todoItem = document.createElement("div");
todoItem.classList.add("todoWrapper");
const checkbox = createCheckbox(todo.checked);
const todoText = createTodoText(todo.text, todo.checked);
const deleteButton = createDeleteButton(todo, todoItem);
}


//입력버튼을 클릭 시 해당 함수가 trigger 되게 addEventListener 등록
addTodo.addEventListener("click", () => {
const text = todoInput.value.trim(); //입력한 todo의 불필요한 공백 제거
Copy link
Collaborator

Choose a reason for hiding this comment

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

trim()으로 공백 예외처리까지 너무 좋습니다

Comment on lines +76 to +78
storedTodos.forEach((todo) => {
addTodoItem(todo);
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

forEach나 filter같은 고차함수 사용도 잘 하시는 것 같아요

Comment on lines +126 to +141
html {
font-size: 10px; /* Default font size */

/* Media query for tablet */
@media (min-width: 768px) and (max-width: 1023px) {
font-size: 8px;
}

/* Media query for mobile */
@media (min-width: 450px) and (max-width: 768px) {
font-size: 6px;
}
@media (max-width: 450px) {
font-size: 4px;
}
}
Copy link

Choose a reason for hiding this comment

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

모바일에서의 사용도 고려해서 구현하신게 인상 깊습니다!!

}
});

updateTotalTodoCount();
Copy link

Choose a reason for hiding this comment

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

초기에 화면 접속하면 진행 중, 완료까지 뜨도록 updateCheckedTodoCount() 함수도 호출하면 좋을거 같아요!

Comment on lines +17 to +30
function updateTotalTodoCount() {
totalTodoCount.textContent = "할 일: " + storedTodos.length;
}

//현재 체크된 todo를 계산하여 진행중인 todo와 완료된 todo를 구분하는 함수
function updateCheckedTodoCount() {
const checkboxes = document.querySelectorAll(".todoCheckbox");
const checkedCount = Array.from(checkboxes).filter(
(checkbox) => checkbox.checked
).length; //만들어진 체크박스들을 배열로 불러온 뒤, 각각의 체크 상태를 판단하여 체크된 개수를 저장

nowTodo.textContent = "진행중: " + (storedTodos.length - checkedCount);
doneTodo.textContent = "완료: " + checkedCount;
}
Copy link

Choose a reason for hiding this comment

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

할일, 완료, 진행중 count를 확인할 수 있어 사용성이 정말 좋은거 같습니다!

checkbox.addEventListener("change", () => {
todo.checked = checkbox.checked; //해당 todo의 체크박스 상태가 변하면 그 상태를 저장해 준 후
saveTodos(); //localStorage의 체크박스 상태 변화 저장
todoText.style.textDecoration = checkbox.checked ? "line-through" : "none"; //체크박스가 check 되어있다면 해당 todo에 줄 그어줌
Copy link

Choose a reason for hiding this comment

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

삼항연산자로 line 처리를 해줘서 코드를 간결하게 작성하신게 인상 깊습니다!

@mod-siw
Copy link

mod-siw commented Sep 17, 2023

안녕하세요 1주차 코드 리뷰 파트너 변지혜입니다!😄
반응형도 그렇고, css 관련 코드들을 보며 css 이해도가 높으신 것 같다는 생각을 많이 했던 코드였습니다.
주석도 너무 깔끔하게 잘 써주셔서 다른 코드들도 읽으면서 많이 배울 수 있었습니다!
그럼 1주차 과제 수고하셨고, 스터디 시간에 만나요!

<title>Vanilla Todo</title>
<link rel="stylesheet" href="style.css" />
<title>Todo List</title>
<link rel="stylesheet" href="./css/header.css" />
Copy link

Choose a reason for hiding this comment

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

css 파일 2개로 나눈 거 유지 보수할 때 용이할 것 같아요! 한 페이지에 모든 css를 담아야겠다고 생각했던 과거의 저를 조금 반성하게 되네요ㅎㅎ

display: flex;
align-items: center;
border-radius: 1rem;
}
Copy link

Choose a reason for hiding this comment

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

width 뿐만 아니라 padding, border-radius까지! 모두 반응형이 가능한 단위들로 쓰셨네요! 은연중에 px 단위로 적게 되는 모든 단위들을 반응형이 가능한 단위로 생각할 수 있다는 사실과 함께, 이렇게도 쓸 수 있구나 배워갑니다. 또 반응형 뿐만 아니라 설정들을 적용하는 단위를 쪼개는 것에서 전반적인 css 에 대한 이해도가 높으신 게 느껴지는 것 같습니다ㅎㅎ!

</header>
<div class="todoBoardList"></div>
<div class="boards">
<div class="board" id="toDoBoard">
Copy link

Choose a reason for hiding this comment

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

이번 과제에서는 html 구조가 단순한 편이긴 하지만 1주차 Key Questions 에 Semantic tag에 대한 질문이 있었으니, 이를 활용해서 코드를 짜면 장점들을 이용할 수 있어 좋을 것 같아요!

<header>
<div class="todoTitle">TO-DO LIST</div>
<div class="headerBtnWrapper">
<div class="headerBtn" id="totalTodo"></div>
Copy link

Choose a reason for hiding this comment

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

class / id 이렇게 주면 굳이 상위 div로 묶어주지 않아도 한 번에 스타일 설정할 수 있어서 좋네요! class와 id 사이에 어떤 기준으로 무엇을 선택해야 하나만 고민했었는데 이렇게 한 번에도 쓸 수 있겠구나 배워갑니다😄


nowTodo.textContent = "진행중: " + (storedTodos.length - checkedCount);
doneTodo.textContent = "완료: " + checkedCount;
}
Copy link

Choose a reason for hiding this comment

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

여기서 filter 함수를 이용해 한 번에 체크 상태로 분류하는 거 정말 좋습니다..! 제 코드에도 checked 상태를 관리할 수 있게 수정하면 조금 더 효율적으로 바꿀 수 있겠다 싶어서 와닿는 게 더 크네요ㅎㅎ

const todoText = document.createElement("div");
todoText.textContent = todo.text; //불러온 todo의 text 값을 생성한 요소에 저장
todoText.classList.add("todoText");
todoText.style.textDecoration = todo.checked ? "line-through" : "none"; //불러온 todo의 체크 상태에 따라 줄을 그을지 말지 판단
Copy link

Choose a reason for hiding this comment

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

스타일 관련 설정을 js에서 어떻게 잘 할 수 있을까 고민했었는데 이렇게도 할 수 있군요! 삼항연산자까지 사용해 깔끔하게 표현한 점 좋은 것 같습니다.

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